diff --git a/.codespell/ignore-words.txt b/.codespell/ignore-words.txt index f2a8dc2be59d8..87abbcf8e3d84 100644 --- a/.codespell/ignore-words.txt +++ b/.codespell/ignore-words.txt @@ -20,3 +20,7 @@ deques extint shs pass-thru +numer +arithmetics +ftbfs +straightaway diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index c5039f58b54dc..0ffa4fcfd952a 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,3 +1,15 @@ +#all: Reformat remaining C code that doesn't have a space after a comma. +5b700b0af90591d6b1a2c087bb8de6b7f1bfdd2d + +# ports: Reformat more C and Python source code. +5c32111fa0e31e451b0f1666bdf926be2fdfd82c + +# all: Update Python formatting to latest Black version 22.1.0. +ab2923dfa1174dc177f0a90cb00a7e4ff87958d2 + +# all: Update Python formatting to latest Black version 21.12b0. +3770fab33449a5dadf8eb06edfae0767e75320a6 + # tools/gen-cpydiff.py: Fix formatting of doc strings for new Black. 0f78c36c5aa458a954eed39a46942209107a553e diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 44146662f2f9f..76422b1c3d59b 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -55,8 +55,6 @@ jobs: run: | make -C examples/natmod/features1 make -C examples/natmod/features2 - make -C examples/natmod/btree - make -C examples/natmod/framebuf make -C examples/natmod/uheapq make -C examples/natmod/urandom make -C examples/natmod/ure diff --git a/README.rst b/README.rst index c07591ef3b443..1c5a860df7931 100644 --- a/README.rst +++ b/README.rst @@ -235,7 +235,7 @@ litex alpha mimxrt10xx alpha nrf stable raspberrypi stable -efr32 alpha +silabs (efr32) alpha stm ``F4`` stable | ``others`` beta unix alpha ================ ============================================================ diff --git a/conf.py b/conf.py index 645961c457d3f..29cf7981fc8b3 100644 --- a/conf.py +++ b/conf.py @@ -441,7 +441,7 @@ def autoapi_prepare_jinja_env(jinja_env): # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"cpython": ('https://docs.python.org/3/', None), +intersphinx_mapping = {"python": ('https://docs.python.org/3/', None), "register": ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None), "typing": ('https://circuitpython.readthedocs.io/projects/adafruit-circuitpython-typing/en/latest/', None)} diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c index 843c14342470b..b1f71b8cde4c8 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.c +++ b/devices/ble_hci/common-hal/_bleio/Adapter.c @@ -82,28 +82,23 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) { // Generic Access Service setup. - bleio_uuid_obj_t *generic_access_service_uuid = m_new_obj(bleio_uuid_obj_t); - generic_access_service_uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *generic_access_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); common_hal_bleio_uuid_construct(generic_access_service_uuid, 0x1800, NULL); - bleio_uuid_obj_t *device_name_characteristic_uuid = m_new_obj(bleio_uuid_obj_t); - device_name_characteristic_uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *device_name_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); common_hal_bleio_uuid_construct(device_name_characteristic_uuid, 0x2A00, NULL); - bleio_uuid_obj_t *appearance_characteristic_uuid = m_new_obj(bleio_uuid_obj_t); - appearance_characteristic_uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *appearance_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); common_hal_bleio_uuid_construct(appearance_characteristic_uuid, 0x2A01, NULL); // Not implemented: // Peripheral Preferred Connection Parameters // Central Address Resolution - bleio_service_obj_t *generic_access_service = m_new_obj(bleio_service_obj_t); - generic_access_service->base.type = &bleio_service_type; + bleio_service_obj_t *generic_access_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); common_hal_bleio_service_construct(generic_access_service, generic_access_service_uuid, false); - adapter->device_name_characteristic = m_new_obj(bleio_characteristic_obj_t); - adapter->device_name_characteristic->base.type = &bleio_characteristic_type; + adapter->device_name_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); char generic_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 'n', 'n', 'n', 'n' }; mp_buffer_info_t generic_name_bufinfo = { @@ -132,8 +127,7 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) { .len = sizeof(zero_16), }; - adapter->appearance_characteristic = m_new_obj(bleio_characteristic_obj_t); - adapter->appearance_characteristic->base.type = &bleio_characteristic_type; + adapter->appearance_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); common_hal_bleio_characteristic_construct( adapter->appearance_characteristic, @@ -151,20 +145,16 @@ STATIC void add_generic_services(bleio_adapter_obj_t *adapter) { // Generic Attribute Service setup. - bleio_uuid_obj_t *generic_attribute_service_uuid = m_new_obj(bleio_uuid_obj_t); - generic_attribute_service_uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *generic_attribute_service_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); common_hal_bleio_uuid_construct(generic_attribute_service_uuid, 0x1801, NULL); - bleio_uuid_obj_t *service_changed_characteristic_uuid = m_new_obj(bleio_uuid_obj_t); - service_changed_characteristic_uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *service_changed_characteristic_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); common_hal_bleio_uuid_construct(service_changed_characteristic_uuid, 0x2A05, NULL); - bleio_service_obj_t *generic_attribute_service = m_new_obj(bleio_service_obj_t); - generic_attribute_service->base.type = &bleio_service_type; + bleio_service_obj_t *generic_attribute_service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); common_hal_bleio_service_construct(generic_attribute_service, generic_attribute_service_uuid, false); - adapter->service_changed_characteristic = m_new_obj(bleio_characteristic_obj_t); - adapter->service_changed_characteristic->base.type = &bleio_characteristic_type; + adapter->service_changed_characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); uint32_t zero_32 = 0; mp_buffer_info_t zero_32_value = { @@ -416,8 +406,7 @@ bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *s bt_addr_t addr; hci_check_error(hci_read_bd_addr(&addr)); - bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); - address->base.type = &bleio_address_type; + bleio_address_obj_t *address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); common_hal_bleio_address_construct(address, addr.val, BT_ADDR_LE_PUBLIC); return address; @@ -490,7 +479,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi); // size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX; - // uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size, false); + // uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size); // ble_data_t * sd_data = (ble_data_t *) raw_data; // self->scan_results->common_hal_data = sd_data; // sd_data->len = max_packet_size; diff --git a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c index 5c8c659e36fe8..4150fcfaa025f 100644 --- a/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/CharacteristicBuffer.c @@ -55,8 +55,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe self->characteristic = characteristic; self->timeout_ms = timeout * 1000; // This is a macro. - // true means long-lived, so it won't be moved. - ringbuf_alloc(&self->ringbuf, buffer_size, true); + ringbuf_alloc(&self->ringbuf, buffer_size); bleio_characteristic_set_observer(characteristic, self); } diff --git a/devices/ble_hci/common-hal/_bleio/Connection.c b/devices/ble_hci/common-hal/_bleio/Connection.c index e9e1254b4398d..b1e2ac6f39f19 100644 --- a/devices/ble_hci/common-hal/_bleio/Connection.c +++ b/devices/ble_hci/common-hal/_bleio/Connection.c @@ -453,8 +453,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern // for (size_t i = 0; i < response->count; ++i) { // ble_gattc_service_t *gattc_service = &response->services[i]; -// bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); -// service->base.type = &bleio_service_type; +// bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); // // Initialize several fields at once. // bleio_service_from_connection(service, bleio_connection_new_from_internal(connection)); @@ -466,8 +465,7 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern // if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // // Known service UUID. -// bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); -// uuid->base.type = &bleio_uuid_type; +// bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); // bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); // service->uuid = uuid; // } else { @@ -491,15 +489,14 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern // for (size_t i = 0; i < response->count; ++i) { // ble_gattc_char_t *gattc_char = &response->chars[i]; -// bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); -// characteristic->base.type = &bleio_characteristic_type; +// bleio_characteristic_obj_t *characteristic = +// mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); // bleio_uuid_obj_t *uuid = NULL; // if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // // Known characteristic UUID. -// uuid = m_new_obj(bleio_uuid_obj_t); -// uuid->base.type = &bleio_uuid_type; +// uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); // bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); // } else { // // The discovery response contained a 128-bit UUID that has not yet been registered with the @@ -557,15 +554,13 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern // break; // } -// bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); -// descriptor->base.type = &bleio_descriptor_type; +// bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); // bleio_uuid_obj_t *uuid = NULL; // if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // // Known descriptor UUID. -// uuid = m_new_obj(bleio_uuid_obj_t); -// uuid->base.type = &bleio_uuid_type; +// uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); // bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); // } else { // // The discovery response contained a 128-bit UUID that has not yet been registered with the @@ -750,8 +745,7 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *interna if (internal->connection_obj != mp_const_none) { return internal->connection_obj; } - bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t); - connection->base.type = &bleio_connection_type; + bleio_connection_obj_t *connection = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type); connection->connection = internal; internal->connection_obj = connection; diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c index b690909029e13..24295b025e06e 100644 --- a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c @@ -101,7 +101,7 @@ void common_hal_bleio_packet_buffer_construct( } if (incoming) { - if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size), false)) { + if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + max_packet_size))) { mp_raise_ValueError(translate("Buffer too large and unable to allocate")); } } @@ -110,8 +110,8 @@ void common_hal_bleio_packet_buffer_construct( self->packet_queued = false; self->pending_index = 0; self->pending_size = 0; - self->outgoing[0] = m_malloc(max_packet_size, false); - self->outgoing[1] = m_malloc(max_packet_size, false); + self->outgoing[0] = m_malloc(max_packet_size); + self->outgoing[1] = m_malloc(max_packet_size); } else { self->outgoing[0] = NULL; self->outgoing[1] = NULL; diff --git a/devices/ble_hci/common-hal/_bleio/Service.c b/devices/ble_hci/common-hal/_bleio/Service.c index 11b7efd523e42..6aff981f8efc9 100644 --- a/devices/ble_hci/common-hal/_bleio/Service.c +++ b/devices/ble_hci/common-hal/_bleio/Service.c @@ -101,8 +101,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, if (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) { // We need a CCCD if this characteristic is doing notify or indicate. - bleio_descriptor_obj_t *cccd = m_new_obj(bleio_descriptor_obj_t); - cccd->base.type = &bleio_descriptor_type; + bleio_descriptor_obj_t *cccd = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); uint16_t zero = 0; mp_buffer_info_t zero_cccd_value = { diff --git a/docs/index.rst b/docs/index.rst index e49b74b4e3e9d..ba40d18ec42f4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,6 +19,7 @@ Full Table of Contents :caption: API and Usage ../shared-bindings/index.rst + library/index.rst supported_ports.rst troubleshooting.rst libraries.rst @@ -32,13 +33,12 @@ Full Table of Contents design_guide porting common_hal + reference/mpyfiles.rst + reference/glossary.rst .. toctree:: :maxdepth: 2 - :caption: MicroPython specific - - library/index.rst - reference/glossary.rst + :caption: Python stand .. toctree:: :maxdepth: 1 diff --git a/docs/library/array.rst b/docs/library/array.rst index 8801ca6ab9cef..a78ba824046fe 100644 --- a/docs/library/array.rst +++ b/docs/library/array.rst @@ -1,10 +1,10 @@ :mod:`array` -- arrays of numeric data -======================================= +====================================== .. module:: array :synopsis: efficient arrays of numeric data -|see_cpython_module| :mod:`cpython:array`. +|see_cpython_module| :mod:`python:array`. Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``, ``L``, ``q``, ``Q``, ``f``, ``d`` (the latter 2 depending on the diff --git a/docs/library/binascii.rst b/docs/library/binascii.rst index f43eeb83c4ccf..1eba46652d7fc 100644 --- a/docs/library/binascii.rst +++ b/docs/library/binascii.rst @@ -1,10 +1,10 @@ :mod:`binascii` -- binary/ASCII conversions -============================================ +=========================================== .. module:: binascii :synopsis: binary/ASCII conversions -|see_cpython_module| :mod:`cpython:binascii`. +|see_cpython_module| :mod:`python:binascii`. This module implements conversions between binary data and various encodings of it in ASCII form (in both directions). @@ -31,11 +31,11 @@ Functions Conforms to `RFC 2045 s.6.8 `_. Returns a bytes object. -.. function:: b2a_base64(data) +.. function:: b2a_base64(data, *, newline=True) Encode binary data in base64 format, as in `RFC 3548 `_. Returns the encoded data - followed by a newline character, as a bytes object. + followed by a newline character if ``newline`` is true, as a bytes object. .. function:: crc32(data, value=0, /) diff --git a/docs/library/btree.rst b/docs/library/btree.rst deleted file mode 100644 index e160ebe13def7..0000000000000 --- a/docs/library/btree.rst +++ /dev/null @@ -1,161 +0,0 @@ -:mod:`btree` -- simple BTree database -===================================== - -.. include:: ../templates/unsupported_in_circuitpython.inc - -.. module:: btree - :synopsis: simple BTree database - -The ``btree`` module implements a simple key-value database using external -storage (disk files, or in general case, a random-access ``stream``). Keys are -stored sorted in the database, and besides efficient retrieval by a key -value, a database also supports efficient ordered range scans (retrieval -of values with the keys in a given range). On the application interface -side, BTree database work as close a possible to a way standard `dict` -type works, one notable difference is that both keys and values must -be `bytes` objects (so, if you want to store objects of other types, you -need to serialize them to `bytes` first). - -The module is based on the well-known BerkelyDB library, version 1.xx. - -Example:: - - import btree - - # First, we need to open a stream which holds a database - # This is usually a file, but can be in-memory database - # using io.BytesIO, a raw flash partition, etc. - # Oftentimes, you want to create a database file if it doesn't - # exist and open if it exists. Idiom below takes care of this. - # DO NOT open database with "a+b" access mode. - try: - f = open("mydb", "r+b") - except OSError: - f = open("mydb", "w+b") - - # Now open a database itself - db = btree.open(f) - - # The keys you add will be sorted internally in the database - db[b"3"] = b"three" - db[b"1"] = b"one" - db[b"2"] = b"two" - - # Assume that any changes are cached in memory unless - # explicitly flushed (or database closed). Flush database - # at the end of each "transaction". - db.flush() - - # Prints b'two' - print(db[b"2"]) - - # Iterate over sorted keys in the database, starting from b"2" - # until the end of the database, returning only values. - # Mind that arguments passed to values() method are *key* values. - # Prints: - # b'two' - # b'three' - for word in db.values(b"2"): - print(word) - - del db[b"2"] - - # No longer true, prints False - print(b"2" in db) - - # Prints: - # b"1" - # b"3" - for key in db: - print(key) - - db.close() - - # Don't forget to close the underlying stream! - f.close() - - -Functions ---------- - -.. function:: open(stream, *, flags=0, pagesize=0, cachesize=0, minkeypage=0) - - Open a database from a random-access ``stream`` (like an open file). All - other parameters are optional and keyword-only, and allow to tweak advanced - parameters of the database operation (most users will not need them): - - * *flags* - Currently unused. - * *pagesize* - Page size used for the nodes in BTree. Acceptable range - is 512-65536. If 0, a port-specific default will be used, optimized for - port's memory usage and/or performance. - * *cachesize* - Suggested memory cache size in bytes. For a - board with enough memory using larger values may improve performance. - Cache policy is as follows: entire cache is not allocated at once; - instead, accessing a new page in database will allocate a memory buffer - for it, until value specified by *cachesize* is reached. Then, these - buffers will be managed using LRU (least recently used) policy. More - buffers may still be allocated if needed (e.g., if a database contains - big keys and/or values). Allocated cache buffers aren't reclaimed. - * *minkeypage* - Minimum number of keys to store per page. Default value - of 0 equivalent to 2. - - Returns a BTree object, which implements a dictionary protocol (set - of methods), and some additional methods described below. - -Methods -------- - -.. method:: btree.close() - - Close the database. It's mandatory to close the database at the end of - processing, as some unwritten data may be still in the cache. Note that - this does not close underlying stream with which the database was opened, - it should be closed separately (which is also mandatory to make sure that - data flushed from buffer to the underlying storage). - -.. method:: btree.flush() - - Flush any data in cache to the underlying stream. - -.. method:: btree.__getitem__(key) - btree.get(key, default=None, /) - btree.__setitem__(key, val) - btree.__delitem__(key) - btree.__contains__(key) - - Standard dictionary methods. - -.. method:: btree.__iter__() - - A BTree object can be iterated over directly (similar to a dictionary) - to get access to all keys in order. - -.. method:: btree.keys([start_key, [end_key, [flags]]]) - btree.values([start_key, [end_key, [flags]]]) - btree.items([start_key, [end_key, [flags]]]) - - These methods are similar to standard dictionary methods, but also can - take optional parameters to iterate over a key sub-range, instead of - the entire database. Note that for all 3 methods, *start_key* and - *end_key* arguments represent key values. For example, `values()` - method will iterate over values corresponding to they key range - given. None values for *start_key* means "from the first key", no - *end_key* or its value of None means "until the end of database". - By default, range is inclusive of *start_key* and exclusive of - *end_key*, you can include *end_key* in iteration by passing *flags* - of `btree.INCL`. You can iterate in descending key direction - by passing *flags* of `btree.DESC`. The flags values can be ORed - together. - -Constants ---------- - -.. data:: INCL - - A flag for `keys()`, `values()`, `items()` methods to specify that - scanning should be inclusive of the end key. - -.. data:: DESC - - A flag for `keys()`, `values()`, `items()` methods to specify that - scanning should be in descending direction of keys. diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst index 3a675e7ec1070..6003c23fb131b 100644 --- a/docs/library/builtins.rst +++ b/docs/library/builtins.rst @@ -33,7 +33,7 @@ Functions and types .. class:: bytes() - |see_cpython| `bytes`. + |see_cpython| `python:bytes`. .. function:: callable() @@ -68,7 +68,7 @@ Functions and types .. class:: frozenset() -`frozenset()` is not enabled on non-Express CircuitPython boards. +`frozenset()` is not enabled on the smallest CircuitPython boards for space reasons. .. function:: getattr() @@ -88,12 +88,12 @@ Functions and types .. classmethod:: from_bytes(bytes, byteorder) - In CircuitPython, ``byteorder`` parameter must be positional (this is + In CircuitPython, the ``byteorder`` parameter must be positional (this is compatible with CPython). .. method:: to_bytes(size, byteorder) - In CircuitPython, ``byteorder`` parameter must be positional (this is + In CircuitPython, the ``byteorder`` parameter must be positional (this is compatible with CPython). .. function:: isinstance() @@ -138,7 +138,7 @@ Functions and types .. function:: reversed() -`reversed()` is not enabled on non-Express CircuitPython boards. +`reversed()` is not enabled on the smallest CircuitPython boards for space reasons. .. function:: round() @@ -224,10 +224,14 @@ Exceptions .. exception:: SystemExit + |see_cpython| `python:SystemExit`. + .. exception:: TimeoutError .. exception:: TypeError + |see_cpython| `python:TypeError`. + .. exception:: UnicodeError .. exception:: ValueError diff --git a/docs/library/collections.rst b/docs/library/collections.rst index 2cc1a215d1d0e..7cc6d9989b6a0 100644 --- a/docs/library/collections.rst +++ b/docs/library/collections.rst @@ -1,12 +1,12 @@ :mod:`collections` -- collection and container types -===================================================== +==================================================== -.. include:: ../templates/unsupported_in_circuitpython.inc +**Limitations:** Not implemented on the smallest CircuitPython boards for space reasons. .. module:: collections :synopsis: collection and container types -|see_cpython_module| :mod:`cpython:collections`. +|see_cpython_module| :mod:`python:collections`. This module implements advanced collection and container types to hold/accumulate various objects. @@ -14,7 +14,7 @@ hold/accumulate various objects. Classes ------- -.. function:: deque(iterable, maxlen[, flags]) +.. class:: deque(iterable, maxlen[, flags]) Deques (double-ended queues) are a list-like container that support O(1) appends and pops from either side of the deque. New deques are created @@ -59,7 +59,7 @@ Classes print(t1.name) assert t2.name == t2[1] -.. function:: OrderedDict(...) +.. class:: OrderedDict(...) ``dict`` type subclass which remembers and preserves the order of keys added. When ordered dict is iterated over, keys/items are returned in diff --git a/docs/library/errno.rst b/docs/library/errno.rst index 1f2c7e14eabf6..61970291df57a 100644 --- a/docs/library/errno.rst +++ b/docs/library/errno.rst @@ -4,10 +4,10 @@ .. module:: errno :synopsis: system error codes -|see_cpython_module| :mod:`cpython:errno`. +|see_cpython_module| :mod:`python:errno`. This module provides access to symbolic error codes for `OSError` exception. -A particular inventory of codes depends on :term:`MicroPython port`. +The codes available may vary per CircuitPython build. Constants --------- @@ -15,14 +15,13 @@ Constants .. data:: EEXIST, EAGAIN, etc. Error codes, based on ANSI C/POSIX standard. All error codes start with - "E". As mentioned above, inventory of the codes depends on - :term:`MicroPython port`. Errors are usually accessible as ``exc.args[0]`` + "E". Errors are usually accessible as ``exc.errno`` where ``exc`` is an instance of `OSError`. Usage example:: try: os.mkdir("my_dir") except OSError as exc: - if exc.args[0] == errno.EEXIST: + if exc.errno == errno.EEXIST: print("Directory already exists") .. data:: errorcode diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst deleted file mode 100644 index 421066b82d10e..0000000000000 --- a/docs/library/framebuf.rst +++ /dev/null @@ -1,170 +0,0 @@ -:mod:`framebuf` --- frame buffer manipulation -============================================= - -.. include:: ../templates/unsupported_in_circuitpython.inc - -.. module:: framebuf - :synopsis: Frame buffer manipulation - -This module provides a general frame buffer which can be used to create -bitmap images, which can then be sent to a display. - -class FrameBuffer ------------------ - -The FrameBuffer class provides a pixel buffer which can be drawn upon with -pixels, lines, rectangles, text and even other FrameBuffer's. It is useful -when generating output for displays. - -For example:: - - import framebuf - - # FrameBuffer needs 2 bytes for every RGB565 pixel - fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565) - - fbuf.fill(0) - fbuf.text('MicroPython!', 0, 0, 0xffff) - fbuf.hline(0, 9, 96, 0xffff) - -Constructors ------------- - -.. class:: FrameBuffer(buffer, width, height, format, stride=width, /) - - Construct a FrameBuffer object. The parameters are: - - - *buffer* is an object with a buffer protocol which must be large - enough to contain every pixel defined by the width, height and - format of the FrameBuffer. - - *width* is the width of the FrameBuffer in pixels - - *height* is the height of the FrameBuffer in pixels - - *format* specifies the type of pixel used in the FrameBuffer; - permissible values are listed under Constants below. These set the - number of bits used to encode a color value and the layout of these - bits in *buffer*. - Where a color value c is passed to a method, c is a small integer - with an encoding that is dependent on the format of the FrameBuffer. - - *stride* is the number of pixels between each horizontal line - of pixels in the FrameBuffer. This defaults to *width* but may - need adjustments when implementing a FrameBuffer within another - larger FrameBuffer or screen. The *buffer* size must accommodate - an increased step size. - - One must specify valid *buffer*, *width*, *height*, *format* and - optionally *stride*. Invalid *buffer* size or dimensions may lead to - unexpected errors. - -Drawing primitive shapes ------------------------- - -The following methods draw shapes onto the FrameBuffer. - -.. method:: FrameBuffer.fill(c) - - Fill the entire FrameBuffer with the specified color. - -.. method:: FrameBuffer.pixel(x, y[, c]) - - If *c* is not given, get the color value of the specified pixel. - If *c* is given, set the specified pixel to the given color. - -.. method:: FrameBuffer.hline(x, y, w, c) -.. method:: FrameBuffer.vline(x, y, h, c) -.. method:: FrameBuffer.line(x1, y1, x2, y2, c) - - Draw a line from a set of coordinates using the given color and - a thickness of 1 pixel. The `line` method draws the line up to - a second set of coordinates whereas the `hline` and `vline` - methods draw horizontal and vertical lines respectively up to - a given length. - -.. method:: FrameBuffer.rect(x, y, w, h, c) -.. method:: FrameBuffer.fill_rect(x, y, w, h, c) - - Draw a rectangle at the given location, size and color. The `rect` - method draws only a 1 pixel outline whereas the `fill_rect` method - draws both the outline and interior. - -Drawing text ------------- - -.. method:: FrameBuffer.text(s, x, y[, c]) - - Write text to the FrameBuffer using the the coordinates as the upper-left - corner of the text. The color of the text can be defined by the optional - argument but is otherwise a default value of 1. All characters have - dimensions of 8x8 pixels and there is currently no way to change the font. - - -Other methods -------------- - -.. method:: FrameBuffer.scroll(xstep, ystep) - - Shift the contents of the FrameBuffer by the given vector. This may - leave a footprint of the previous colors in the FrameBuffer. - -.. method:: FrameBuffer.blit(fbuf, x, y, key=-1, palette=None) - - Draw another FrameBuffer on top of the current one at the given coordinates. - If *key* is specified then it should be a color integer and the - corresponding color will be considered transparent: all pixels with that - color value will not be drawn. - - The *palette* argument enables blitting between FrameBuffers with differing - formats. Typical usage is to render a monochrome or grayscale glyph/icon to - a color display. The *palette* is a FrameBuffer instance whose format is - that of the current FrameBuffer. The *palette* height is one pixel and its - pixel width is the number of colors in the source FrameBuffer. The *palette* - for an N-bit source needs 2**N pixels; the *palette* for a monochrome source - would have 2 pixels representing background and foreground colors. The - application assigns a color to each pixel in the *palette*. The color of the - current pixel will be that of that *palette* pixel whose x position is the - color of the corresponding source pixel. - -Constants ---------- - -.. data:: framebuf.MONO_VLSB - - Monochrome (1-bit) color format - This defines a mapping where the bits in a byte are vertically mapped with - bit 0 being nearest the top of the screen. Consequently each byte occupies - 8 vertical pixels. Subsequent bytes appear at successive horizontal - locations until the rightmost edge is reached. Further bytes are rendered - at locations starting at the leftmost edge, 8 pixels lower. - -.. data:: framebuf.MONO_HLSB - - Monochrome (1-bit) color format - This defines a mapping where the bits in a byte are horizontally mapped. - Each byte occupies 8 horizontal pixels with bit 7 being the leftmost. - Subsequent bytes appear at successive horizontal locations until the - rightmost edge is reached. Further bytes are rendered on the next row, one - pixel lower. - -.. data:: framebuf.MONO_HMSB - - Monochrome (1-bit) color format - This defines a mapping where the bits in a byte are horizontally mapped. - Each byte occupies 8 horizontal pixels with bit 0 being the leftmost. - Subsequent bytes appear at successive horizontal locations until the - rightmost edge is reached. Further bytes are rendered on the next row, one - pixel lower. - -.. data:: framebuf.RGB565 - - Red Green Blue (16-bit, 5+6+5) color format - -.. data:: framebuf.GS2_HMSB - - Grayscale (2-bit) color format - -.. data:: framebuf.GS4_HMSB - - Grayscale (4-bit) color format - -.. data:: framebuf.GS8 - - Grayscale (8-bit) color format diff --git a/docs/library/gc.rst b/docs/library/gc.rst index 1a6c3d68c053a..32afc7e982ff1 100644 --- a/docs/library/gc.rst +++ b/docs/library/gc.rst @@ -1,12 +1,10 @@ :mod:`gc` -- control the garbage collector ========================================== -.. include:: ../templates/unsupported_in_circuitpython.inc - .. module:: gc :synopsis: control the garbage collector -|see_cpython_module| :mod:`cpython:gc`. +|see_cpython_module| :mod:`python:gc`. Functions --------- @@ -63,6 +61,6 @@ Functions .. admonition:: Difference to CPython :class: attention - This function is a a MicroPython extension. CPython has a similar + This function is a MicroPython extension. CPython has a similar function - ``set_threshold()``, but due to different GC implementations, its signature and semantics are different. diff --git a/docs/library/heapq.rst b/docs/library/heapq.rst index 7269422847452..71a998479f9a7 100644 --- a/docs/library/heapq.rst +++ b/docs/library/heapq.rst @@ -6,7 +6,7 @@ .. module:: heapq :synopsis: heap queue algorithm -|see_cpython_module| :mod:`cpython:heapq`. +|see_cpython_module| :mod:`python:heapq`. This module implements the `min heap queue algorithm `_. diff --git a/docs/library/index.rst b/docs/library/index.rst index 2a8e37a8f4312..7fda1abd6081b 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -1,21 +1,19 @@ .. _micropython_lib: -MicroPython libraries -===================== +Standard Libraries +================== -Python standard libraries and micro-libraries ---------------------------------------------- +Python standard libraries +------------------------- -The libraries below are inherited from MicroPython. -They are similar to the standard Python libraries with the same name. -They implement a subset of or a variant of the corresponding -standard Python library. +The libraries below implement a subset of the corresponding +standard Python (CPython) library. They are implemented in C, not Python. CircuitPython's long-term goal is that code written in CircuitPython using Python standard libraries will be runnable on CPython without changes. These libraries are not enabled on CircuitPython builds with -limited flash memory, usually on non-Express builds: +limited flash memory: ``binascii``, ``errno``, ``json``, ``re``. These libraries are not currently enabled in any CircuitPython build, but may be in the future: @@ -38,11 +36,11 @@ These libraries are not currently enabled in any CircuitPython build, but may be ctypes.rst select.rst -Omitted functions in the ``string`` library -------------------------------------------- +Omitted ``string`` functions +---------------------------- A few string operations are not enabled on small builds -(usually non-Express), due to limited flash memory: +due to limited flash memory: ``string.center()``, ``string.partition()``, ``string.splitlines()``, ``string.reversed()``. @@ -50,13 +48,10 @@ A few string operations are not enabled on small builds CircuitPython/MicroPython-specific libraries -------------------------------------------- -Functionality specific to the CircuitPython/MicroPython implementation is available in -the following libraries. These libraries may change significantly or be removed in future -versions of CircuitPython. +Functionality specific to the CircuitPython/MicroPython implementations is available in +the following libraries. .. toctree:: :maxdepth: 1 - btree.rst - framebuf.rst micropython.rst diff --git a/docs/library/io.rst b/docs/library/io.rst index 37e3eb7c941f0..ad1fb03c77729 100644 --- a/docs/library/io.rst +++ b/docs/library/io.rst @@ -1,10 +1,10 @@ :mod:`io` -- input/output streams -================================== +================================= .. module:: io :synopsis: input/output streams -|see_cpython_module| :mod:`cpython:io`. +|see_cpython_module| :mod:`python:io`. This module contains additional types of ``stream`` (file-like) objects and helper functions. @@ -112,3 +112,20 @@ Classes .. method:: getvalue() Get the current contents of the underlying buffer which holds data. + +.. class:: StringIO(alloc_size) + :noindex: +.. class:: BytesIO(alloc_size) + :noindex: + + Create an empty `StringIO`/`BytesIO` object, preallocated to hold up + to *alloc_size* number of bytes. That means that writing that amount + of bytes won't lead to reallocation of the buffer, and thus won't hit + out-of-memory situation or lead to memory fragmentation. These constructors + are a MicroPython extension and are recommended for usage only in special + cases and in system-level libraries, not for end-user applications. + + .. admonition:: Difference to CPython + :class: attention + + These constructors are a MicroPython extension. diff --git a/docs/library/json.rst b/docs/library/json.rst index 21574e556b5ca..d65bc0e5a2460 100644 --- a/docs/library/json.rst +++ b/docs/library/json.rst @@ -1,10 +1,10 @@ :mod:`json` -- JSON encoding and decoding -========================================== +========================================= .. module:: json :synopsis: JSON encoding and decoding -|see_cpython_module| :mod:`cpython:json`. +|see_cpython_module| :mod:`python:json`. This modules allows to convert between Python objects and the JSON data format. @@ -12,14 +12,20 @@ data format. Functions --------- -.. function:: dump(obj, stream) +.. function:: dump(obj, stream, separators=None) Serialise ``obj`` to a JSON string, writing it to the given *stream*. -.. function:: dumps(obj) + If specified, separators should be an ``(item_separator, key_separator)`` + tuple. The default is ``(', ', ': ')``. To get the most compact JSON + representation, you should specify ``(',', ':')`` to eliminate whitespace. + +.. function:: dumps(obj, separators=None) Return ``obj`` represented as a JSON string. + The arguments have the same meaning as in `dump`. + .. function:: load(stream) Parse the given ``stream``, interpreting it as a JSON string and diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst index dddb813d3478b..166192de3a38e 100644 --- a/docs/library/micropython.rst +++ b/docs/library/micropython.rst @@ -1,7 +1,5 @@ -:mod:`micropython` -- access and control MicroPython internals -============================================================== - -.. include:: ../templates/unsupported_in_circuitpython.inc +:mod:`micropython` -- MicroPython extensions and internals +========================================================== .. module:: micropython :synopsis: access and control MicroPython internals @@ -11,7 +9,7 @@ Functions .. function:: const(expr) - Used to declare that the expression is a constant so that the compile can + Used to declare that the expression is a constant so that the compiler can optimise it. The use of this function should be as follows:: from micropython import const @@ -28,111 +26,3 @@ Functions provided as part of the :mod:`micropython` module mainly so that scripts can be written which run under both CPython and MicroPython, by following the above pattern. - -.. function:: opt_level([level]) - - If *level* is given then this function sets the optimisation level for subsequent - compilation of scripts, and returns ``None``. Otherwise it returns the current - optimisation level. - - The optimisation level controls the following compilation features: - - - Assertions: at level 0 assertion statements are enabled and compiled into the - bytecode; at levels 1 and higher assertions are not compiled. - - Built-in ``__debug__`` variable: at level 0 this variable expands to ``True``; - at levels 1 and higher it expands to ``False``. - - Source-code line numbers: at levels 0, 1 and 2 source-code line number are - stored along with the bytecode so that exceptions can report the line number - they occurred at; at levels 3 and higher line numbers are not stored. - - The default optimisation level is usually level 0. - -.. function:: mem_info([verbose]) - - Print information about currently used memory. If the *verbose* argument - is given then extra information is printed. - - The information that is printed is implementation dependent, but currently - includes the amount of stack and heap used. In verbose mode it prints out - the entire heap indicating which blocks are used and which are free. - -.. function:: qstr_info([verbose]) - - Print information about currently interned strings. If the *verbose* - argument is given then extra information is printed. - - The information that is printed is implementation dependent, but currently - includes the number of interned strings and the amount of RAM they use. In - verbose mode it prints out the names of all RAM-interned strings. - -.. function:: stack_use() - - Return an integer representing the current amount of stack that is being - used. The absolute value of this is not particularly useful, rather it - should be used to compute differences in stack usage at different points. - -.. function:: heap_lock() -.. function:: heap_unlock() -.. function:: heap_locked() - - Lock or unlock the heap. When locked no memory allocation can occur and a - ``MemoryError`` will be raised if any heap allocation is attempted. - `heap_locked()` returns a true value if the heap is currently locked. - - These functions can be nested, ie `heap_lock()` can be called multiple times - in a row and the lock-depth will increase, and then `heap_unlock()` must be - called the same number of times to make the heap available again. - - Both `heap_unlock()` and `heap_locked()` return the current lock depth - (after unlocking for the former) as a non-negative integer, with 0 meaning - the heap is not locked. - - If the REPL becomes active with the heap locked then it will be forcefully - unlocked. - - Note: `heap_locked()` is not enabled on most ports by default, - requires ``MICROPY_PY_MICROPYTHON_HEAP_LOCKED``. - -.. function:: kbd_intr(chr) - - Set the character that will raise a `KeyboardInterrupt` exception. By - default this is set to 3 during script execution, corresponding to Ctrl-C. - Passing -1 to this function will disable capture of Ctrl-C, and passing 3 - will restore it. - - This function can be used to prevent the capturing of Ctrl-C on the - incoming stream of characters that is usually used for the REPL, in case - that stream is used for other purposes. - -.. function:: schedule(func, arg) - - Schedule the function *func* to be executed "very soon". The function - is passed the value *arg* as its single argument. "Very soon" means that - the MicroPython runtime will do its best to execute the function at the - earliest possible time, given that it is also trying to be efficient, and - that the following conditions hold: - - - A scheduled function will never preempt another scheduled function. - - Scheduled functions are always executed "between opcodes" which means - that all fundamental Python operations (such as appending to a list) - are guaranteed to be atomic. - - A given port may define "critical regions" within which scheduled - functions will never be executed. Functions may be scheduled within - a critical region but they will not be executed until that region - is exited. An example of a critical region is a preempting interrupt - handler (an IRQ). - - A use for this function is to schedule a callback from a preempting IRQ. - Such an IRQ puts restrictions on the code that runs in the IRQ (for example - the heap may be locked) and scheduling a function to call later will lift - those restrictions. - - Note: If `schedule()` is called from a preempting IRQ, when memory - allocation is not allowed and the callback to be passed to `schedule()` is - a bound method, passing this directly will fail. This is because creating a - reference to a bound method causes memory allocation. A solution is to - create a reference to the method in the class constructor and to pass that - reference to `schedule()`. - - There is a finite queue to hold the scheduled functions and `schedule()` - will raise a `RuntimeError` if the queue is full. diff --git a/docs/library/re.rst b/docs/library/re.rst index d09ef59ba47e3..19b15d2d2c299 100644 --- a/docs/library/re.rst +++ b/docs/library/re.rst @@ -1,10 +1,10 @@ :mod:`re` -- simple regular expressions -======================================== +======================================= .. module:: re :synopsis: regular expressions -|see_cpython_module| :mod:`cpython:re`. +|see_cpython_module| :mod:`python:re`. This module implements regular expression operations. Regular expression syntax supported is a subset of CPython ``re`` module (and actually is diff --git a/docs/library/select.rst b/docs/library/select.rst index 84792bc53a599..08bbe08df2c69 100644 --- a/docs/library/select.rst +++ b/docs/library/select.rst @@ -1,8 +1,6 @@ :mod:`select` -- wait for events on a set of streams ==================================================== -.. include:: ../templates/unsupported_in_circuitpython.inc - .. module:: select :synopsis: wait for events on a set of streams @@ -86,7 +84,7 @@ Methods .. method:: poll.ipoll(timeout=-1, flags=0, /) Like :meth:`poll.poll`, but instead returns an iterator which yields a - ``callee-owned tuples``. This function provides efficient, allocation-free + "callee-owned tuple". This function provides an efficient, allocation-free way to poll on streams. If *flags* is 1, one-shot behaviour for events is employed: streams for diff --git a/docs/library/sys.rst b/docs/library/sys.rst index a0675f0f5000a..aa0a382748c13 100644 --- a/docs/library/sys.rst +++ b/docs/library/sys.rst @@ -1,12 +1,10 @@ :mod:`sys` -- system specific functions -======================================== - -.. include:: ../templates/unsupported_in_circuitpython.inc +======================================= .. module:: sys :synopsis: system specific functions -|see_cpython_module| :mod:`cpython:sys`. +|see_cpython_module| :mod:`python:sys`. Functions --------- @@ -35,6 +33,7 @@ Constants * *name* - string "circuitpython" * *version* - tuple (major, minor, micro), e.g. (1, 7, 0) + * *_mpy* - supported mpy file-format version (optional attribute) This object is the recommended way to distinguish CircuitPython from other Python implementations (note that it still may not exist in the very @@ -97,6 +96,12 @@ Constants If you need to check whether your program runs on CircuitPython (vs other Python implementation), use `sys.implementation` instead. +.. data:: ps1 + ps2 + + Mutable attributes holding strings, which are used for the REPL prompt. The defaults + give the standard Python prompt of ``>>>`` and ``...``. + .. data:: stderr Standard error ``stream``. @@ -109,6 +114,14 @@ Constants Standard output ``stream``. +.. data:: tracebacklimit + + A mutable attribute holding an integer value which is the maximum number of traceback + entries to store in an exception. Set to 0 to disable adding tracebacks. Defaults + to 1000. + + Note: this is not available on all ports. + .. data:: version Python language version that this implementation conforms to, as a string. diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 5aae70af0a719..fe65ddaa1466a 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -159,7 +159,7 @@ Glossary typically accessible on a host PC via USB. stream - Also known as a "file-like object". An Python object which provides + Also known as a "file-like object". A Python object which provides sequential read-write access to the underlying data. A stream object implements a corresponding interface, which consists of methods like ``read()``, ``write()``, ``readinto()``, ``seek()``, ``flush()``, diff --git a/docs/reference/mpyfiles.rst b/docs/reference/mpyfiles.rst new file mode 100644 index 0000000000000..b65f62f9ca9a0 --- /dev/null +++ b/docs/reference/mpyfiles.rst @@ -0,0 +1,199 @@ +.. _mpy_files: + +MicroPython .mpy files +====================== + +MicroPython defines the concept of an .mpy file which is a binary container +file format that holds precompiled code, and which can be imported like a +normal .py module. The file ``foo.mpy`` can be imported via ``import foo``, +as long as ``foo.mpy`` can be found in the usual way by the import machinery. +Usually, each directory listed in ``sys.path`` is searched in order. When +searching a particular directory ``foo.py`` is looked for first and if that +is not found then ``foo.mpy`` is looked for, then the search continues in the +next directory if neither is found. As such, ``foo.py`` will take precedence +over ``foo.mpy``. + +These .mpy files can contain bytecode which is usually generated from Python +source files (.py files) via the ``mpy-cross`` program. For some architectures +an .mpy file can also contain native machine code, which can be generated in +a variety of ways, most notably from C source code. + +Versioning and compatibility of .mpy files +------------------------------------------ + +A given .mpy file may or may not be compatible with a given MicroPython system. +Compatibility is based on the following: + +* Version of the .mpy file: the version of the file must match the version + supported by the system loading it. + +* Sub-version of the .mpy file: if the .mpy file contains native machine code + then the sub-version of the file must match the version support by the + system loading it. Otherwise, if there is no native machine code in the .mpy + file, then the sub-version is ignored when loading. + +* Small integer bits: the .mpy file will require a minimum number of bits in + a small integer and the system loading it must support at least this many + bits. + +* Native architecture: if the .mpy file contains native machine code then + it will specify the architecture of that machine code and the system + loading it must support execution of that architecture's code. + +If a MicroPython system supports importing .mpy files then the +``sys.implementation._mpy`` field will exist and return an integer which +encodes the version (lower 8 bits), features and native architecture. + +Trying to import an .mpy file that fails one of the first four tests will +raise ``ValueError('incompatible .mpy file')``. Trying to import an .mpy +file that fails the native architecture test (if it contains native machine +code) will raise ``ValueError('incompatible .mpy arch')``. + +If importing an .mpy file fails then try the following: + +* Determine the .mpy version and flags supported by your MicroPython system + by executing:: + + import sys + sys_mpy = sys.implementation._mpy + arch = [None, 'x86', 'x64', + 'armv6', 'armv6m', 'armv7m', 'armv7em', 'armv7emsp', 'armv7emdp', + 'xtensa', 'xtensawin'][sys_mpy >> 10] + print('mpy version:', sys_mpy & 0xff) + print('mpy flags:', end='') + if arch: + print(' -march=' + arch, end='') + print() + +* Check the validity of the .mpy file by inspecting the first two bytes of + the file. The first byte should be an uppercase 'C' and the second byte + will be the version number, which should match the system version from above. + If it doesn't match then rebuild the .mpy file. + +* Check if the system .mpy version matches the version emitted by ``mpy-cross`` + that was used to build the .mpy file, found by ``mpy-cross --version``. + If it doesn't match then recompile ``mpy-cross`` from the Git repository + checked out at the tag (or hash) reported by ``mpy-cross --version``. + +* Make sure you are using the correct ``mpy-cross`` flags, found by the code + above, or by inspecting the ``MPY_CROSS_FLAGS`` Makefile variable for the + port that you are using. + +The following table shows the correspondence between MicroPython release +and .mpy version. + +=================== ============ +MicroPython release .mpy version +=================== ============ +v1.19 and up 6 +v1.12 - v1.18 5 +v1.11 4 +v1.9.3 - v1.10 3 +v1.9 - v1.9.2 2 +v1.5.1 - v1.8.7 0 +=================== ============ + +For completeness, the next table shows the Git commit of the main +MicroPython repository at which the .mpy version was changed. + +=================== ======================================== +.mpy version change Git commit +=================== ======================================== +5 to 6 f2040bfc7ee033e48acef9f289790f3b4e6b74e5 +4 to 5 5716c5cf65e9b2cb46c2906f40302401bdd27517 +3 to 4 9a5f92ea72754c01cc03e5efcdfe94021120531e +2 to 3 ff93fd4f50321c6190e1659b19e64fef3045a484 +1 to 2 dd11af209d226b7d18d5148b239662e30ed60bad +0 to 1 6a11048af1d01c78bdacddadd1b72dc7ba7c6478 +initial version 0 d8c834c95d506db979ec871417de90b7951edc30 +=================== ======================================== + +Binary encoding of .mpy files +----------------------------- + +MicroPython .mpy files are a binary container format with code objects (bytecode +and native machine code) stored internally in a nested hierarchy. The code for +the outer module is stored first, and then its children follow. Each child may +have further children, for example in the case of a class having methods, or a +function defining a lambda or comprehension. To keep files small while still +providing a large range of possible values it uses the concept of a +variably-encoded-unsigned-integer (vuint) in many places. Similar to utf-8 +encoding, this encoding stores 7 bits per byte with the 8th bit (MSB) set +if one or more bytes follow. The bits of the unsigned integer are stored +in the vuint in LSB form. + +The top-level of an .mpy file consists of three parts: + +* The header. + +* The global qstr and constant tables. + +* The raw-code for the outer scope of the module. + This outer scope is executed when the .mpy file is imported. + +You can inspect the contents of a .mpy file by using ``mpy-tool.py``, for +example (run from the root of the main MicroPython repository):: + + $ ./tools/mpy-tool.py -xd myfile.mpy + +The header +~~~~~~~~~~ + +The .mpy header is: + +====== ================================ +size field +====== ================================ +byte value 0x43 (ASCII 'C') +byte .mpy version number +byte feature flags +byte number of bits in a small int +====== ================================ + +The global qstr and constant tables +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +An .mpy file contains a single qstr table, and a single constant object table. +These are global to the .mpy file, they are referenced by all nested raw-code +objects. The qstr table maps internal qstr number (internal to the .mpy file) +to the resolved qstr number of the runtime that the .mpy file is imported into. +This links the .mpy file with the rest of the system that it executes within. +The constant object table is populated with references to all constant objects +that the .mpy file needs. + +====== ================================ +size field +====== ================================ +vuint number of qstrs +vuint number of constant objects +... qstr data +... encoded constant objects +====== ================================ + +Raw code elements +~~~~~~~~~~~~~~~~~ + +A raw-code element contains code, either bytecode or native machine code. Its +contents are: + +====== ================================ +size field +====== ================================ +vuint type, size and whether there are sub-raw-code elements +... code (bytecode or machine code) +vuint number of sub-raw-code elements (only if non-zero) +... sub-raw-code elements +====== ================================ + +The first vuint in a raw-code element encodes the type of code stored in this +element (the two least-significant bits), whether this raw-code has any +children (the third least-significant bit), and the length of the code that +follows (the amount of RAM to allocate for it). + +Following the vuint comes the code itself. Unless the code type is viper code +with relocations, this code is constant data and does not need to be modified. + +If this raw-code has any children (as indicated by a bit in the first vuint), +following the code comes a vuint counting the number of sub-raw-code elements. + +Finally any sub-raw-code elements are stored, recursively. diff --git a/examples/natmod/btree/Makefile b/examples/natmod/btree/Makefile deleted file mode 100644 index d795102b4aad8..0000000000000 --- 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 b44b7bb3001bf..0000000000000 --- a/examples/natmod/btree/btree_c.c +++ /dev/null @@ -1,148 +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, false); - 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, false); - // 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->ext[0].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->ext[0].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->ext[0].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->ext[0].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_full_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.flags = MP_TYPE_FLAG_EXTENDED; - btree_type.name = MP_QSTR_btree; - btree_type.print = btree_print; - btree_type.ext[0].getiter = btree_getiter; - btree_type.ext[0].iternext = btree_iternext; - btree_type.ext[0].binary_op = btree_binary_op; - btree_type.ext[0].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 bd53c084a13be..0000000000000 --- 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/framebuf/Makefile b/examples/natmod/features3/Makefile similarity index 64% rename from examples/natmod/framebuf/Makefile rename to examples/natmod/features3/Makefile index 2e2b815975432..4a5f71b8f255b 100644 --- a/examples/natmod/framebuf/Makefile +++ b/examples/natmod/features3/Makefile @@ -1,13 +1,14 @@ # Location of top-level MicroPython directory MPY_DIR = ../../.. -# Name of module (different to built-in framebuf so it can coexist) -MOD = framebuf_$(ARCH) +# Name of module +MOD = features3 # Source files (.c or .py) -SRC = framebuf.c +SRC = features3.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/features3/features3.c b/examples/natmod/features3/features3.c new file mode 100644 index 0000000000000..20efd67cdcefd --- /dev/null +++ b/examples/natmod/features3/features3.c @@ -0,0 +1,60 @@ +/* This example demonstrates the following features in a native module: + - using types + - using constant objects + - creating dictionaries +*/ + +// Include the header file to get access to the MicroPython API. +#include "py/dynruntime.h" + +// A function that returns a tuple of object types. +STATIC mp_obj_t get_types(void) { + return mp_obj_new_tuple(9, ((mp_obj_t []) { + MP_OBJ_FROM_PTR(&mp_type_type), + MP_OBJ_FROM_PTR(&mp_type_NoneType), + MP_OBJ_FROM_PTR(&mp_type_bool), + MP_OBJ_FROM_PTR(&mp_type_int), + MP_OBJ_FROM_PTR(&mp_type_str), + MP_OBJ_FROM_PTR(&mp_type_bytes), + MP_OBJ_FROM_PTR(&mp_type_tuple), + MP_OBJ_FROM_PTR(&mp_type_list), + MP_OBJ_FROM_PTR(&mp_type_dict), + })); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_types_obj, get_types); + +// A function that returns a tuple of constant objects. +STATIC mp_obj_t get_const_objects(void) { + return mp_obj_new_tuple(5, ((mp_obj_t []) { + mp_const_none, + mp_const_false, + mp_const_true, + mp_const_empty_bytes, + mp_const_empty_tuple, + })); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(get_const_objects_obj, get_const_objects); + +// A function that creates a dictionary from the given arguments. +STATIC mp_obj_t make_dict(size_t n_args, const mp_obj_t *args) { + mp_obj_t dict = mp_obj_new_dict(n_args / 2); + for (; n_args >= 2; n_args -= 2, args += 2) { + mp_obj_dict_store(dict, args[0], args[1]); + } + return dict; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(make_dict_obj, 0, MP_OBJ_FUN_ARGS_MAX, make_dict); + +// 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_make_dict, MP_OBJ_FROM_PTR(&make_dict_obj)); + mp_store_global(MP_QSTR_get_types, MP_OBJ_FROM_PTR(&get_types_obj)); + mp_store_global(MP_QSTR_get_const_objects, MP_OBJ_FROM_PTR(&get_const_objects_obj)); + + // This must be last, it restores the globals dict. + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c deleted file mode 100644 index 4497ab3318b5f..0000000000000 --- a/examples/natmod/framebuf/framebuf.c +++ /dev/null @@ -1,50 +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_full_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.flags = MP_TYPE_FLAG_EXTENDED; - mp_type_framebuf.name = MP_QSTR_FrameBuffer; - mp_type_framebuf.make_new = framebuf_make_new; - mp_type_framebuf.ext[0].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/usercmodule/cexample/examplemodule.c b/examples/usercmodule/cexample/examplemodule.c index 49ebc7aaaf9d2..93a58be2ed280 100644 --- a/examples/usercmodule/cexample/examplemodule.c +++ b/examples/usercmodule/cexample/examplemodule.c @@ -31,7 +31,4 @@ const mp_obj_module_t example_user_cmodule = { }; // Register the module to make it available in Python. -// Note: the "1" in the third argument means this module is always enabled. -// This "1" can be optionally replaced with a macro like MODULE_CEXAMPLE_ENABLED -// which can then be used to conditionally enable this module. -MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule, 1); +MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule); diff --git a/examples/usercmodule/cppexample/examplemodule.c b/examples/usercmodule/cppexample/examplemodule.c index dfb7856837613..5c84eccd7996f 100644 --- a/examples/usercmodule/cppexample/examplemodule.c +++ b/examples/usercmodule/cppexample/examplemodule.c @@ -22,7 +22,4 @@ const mp_obj_module_t cppexample_user_cmodule = { }; // Register the module to make it available in Python. -// Note: the "1" in the third argument means this module is always enabled. -// This "1" can be optionally replaced with a macro like MODULE_CPPEXAMPLE_ENABLED -// which can then be used to conditionally enable this module. -MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule, 1); +MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule); diff --git a/examples/usercmodule/cppexample/micropython.mk b/examples/usercmodule/cppexample/micropython.mk index e10d965a0011e..0071d4fcc72b6 100644 --- a/examples/usercmodule/cppexample/micropython.mk +++ b/examples/usercmodule/cppexample/micropython.mk @@ -6,7 +6,7 @@ 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) +CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) -std=c++11 # We use C++ features so have to link against the standard library. LDFLAGS_USERMOD += -lstdc++ diff --git a/extmod/axtls-include/axtls_os_port.h b/extmod/axtls-include/axtls_os_port.h index ef2683acfc701..057642f9741b7 100644 --- a/extmod/axtls-include/axtls_os_port.h +++ b/extmod/axtls-include/axtls_os_port.h @@ -26,7 +26,11 @@ #ifndef AXTLS_OS_PORT_H #define AXTLS_OS_PORT_H +#ifndef __ets__ +#include +#endif #include +#include #include "py/stream.h" #include "lib/crypto-algorithms/sha256.h" diff --git a/extmod/extmod.cmake b/extmod/extmod.cmake deleted file mode 100644 index 67f7d8fd39ed3..0000000000000 --- a/extmod/extmod.cmake +++ /dev/null @@ -1,98 +0,0 @@ -# CMake fragment for MicroPython extmod component - -set(MICROPY_EXTMOD_DIR "${MICROPY_DIR}/extmod") -set(MICROPY_OOFATFS_DIR "${MICROPY_DIR}/lib/oofatfs") - -set(MICROPY_SOURCE_EXTMOD - ${MICROPY_DIR}/shared/libc/abort_.c - ${MICROPY_DIR}/shared/libc/printf.c - ${MICROPY_EXTMOD_DIR}/machine_bitstream.c - ${MICROPY_EXTMOD_DIR}/machine_i2c.c - ${MICROPY_EXTMOD_DIR}/machine_mem.c - ${MICROPY_EXTMOD_DIR}/machine_pulse.c - ${MICROPY_EXTMOD_DIR}/machine_pwm.c - ${MICROPY_EXTMOD_DIR}/machine_signal.c - ${MICROPY_EXTMOD_DIR}/machine_spi.c - ${MICROPY_EXTMOD_DIR}/modbluetooth.c - ${MICROPY_EXTMOD_DIR}/modbtree.c - ${MICROPY_EXTMOD_DIR}/modframebuf.c - ${MICROPY_EXTMOD_DIR}/modnetwork.c - ${MICROPY_EXTMOD_DIR}/modonewire.c - ${MICROPY_EXTMOD_DIR}/moduasyncio.c - ${MICROPY_EXTMOD_DIR}/modubinascii.c - ${MICROPY_EXTMOD_DIR}/moducryptolib.c - ${MICROPY_EXTMOD_DIR}/moductypes.c - ${MICROPY_EXTMOD_DIR}/moduhashlib.c - ${MICROPY_EXTMOD_DIR}/moduheapq.c - ${MICROPY_EXTMOD_DIR}/modujson.c - ${MICROPY_EXTMOD_DIR}/moduplatform.c - ${MICROPY_EXTMOD_DIR}/modurandom.c - ${MICROPY_EXTMOD_DIR}/modure.c - ${MICROPY_EXTMOD_DIR}/moduselect.c - ${MICROPY_EXTMOD_DIR}/modusocket.c - ${MICROPY_EXTMOD_DIR}/modussl_axtls.c - ${MICROPY_EXTMOD_DIR}/modussl_mbedtls.c - ${MICROPY_EXTMOD_DIR}/modutimeq.c - ${MICROPY_EXTMOD_DIR}/moduwebsocket.c - ${MICROPY_EXTMOD_DIR}/moduzlib.c - ${MICROPY_EXTMOD_DIR}/modwebrepl.c - ${MICROPY_EXTMOD_DIR}/uos_dupterm.c - ${MICROPY_EXTMOD_DIR}/utime_mphal.c - ${MICROPY_EXTMOD_DIR}/vfs.c - ${MICROPY_EXTMOD_DIR}/vfs_blockdev.c - ${MICROPY_EXTMOD_DIR}/vfs_fat.c - ${MICROPY_EXTMOD_DIR}/vfs_fat_diskio.c - ${MICROPY_EXTMOD_DIR}/vfs_fat_file.c - ${MICROPY_EXTMOD_DIR}/vfs_lfs.c - ${MICROPY_EXTMOD_DIR}/vfs_posix.c - ${MICROPY_EXTMOD_DIR}/vfs_posix_file.c - ${MICROPY_EXTMOD_DIR}/vfs_reader.c - ${MICROPY_EXTMOD_DIR}/virtpin.c - ${MICROPY_EXTMOD_DIR}/nimble/modbluetooth_nimble.c -) - -# Library for btree module and associated code - -set(MICROPY_LIB_BERKELEY_DIR "${MICROPY_DIR}/lib/berkeley-db-1.xx") - -if(EXISTS "${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c") - add_library(micropy_extmod_btree OBJECT - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_conv.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_debug.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_delete.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_get.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_open.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_overflow.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_page.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_put.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_search.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_seq.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_split.c - ${MICROPY_LIB_BERKELEY_DIR}/btree/bt_utils.c - ${MICROPY_LIB_BERKELEY_DIR}/mpool/mpool.c - ) - - target_include_directories(micropy_extmod_btree PRIVATE - ${MICROPY_LIB_BERKELEY_DIR}/PORT/include - ) - - target_compile_definitions(micropy_extmod_btree PRIVATE - __DBINTERFACE_PRIVATE=1 - mpool_error=printf - abort=abort_ - "virt_fd_t=void*" - ) - - # The include directories and compile definitions below are needed to build - # modbtree.c and should be added to the main MicroPython target. - - list(APPEND MICROPY_INC_CORE - "${MICROPY_LIB_BERKELEY_DIR}/PORT/include" - ) - - list(APPEND MICROPY_DEF_CORE - __DBINTERFACE_PRIVATE=1 - "virt_fd_t=void*" - ) -endif() diff --git a/extmod/extmod.mk b/extmod/extmod.mk index 4cdeaedaf99fc..83b1854c1ec57 100644 --- a/extmod/extmod.mk +++ b/extmod/extmod.mk @@ -28,8 +28,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\ lfs1.c \ lfs1_util.c \ ) -else -CFLAGS_MOD += -DMICROPY_VFS_LFS1=0 endif ifeq ($(MICROPY_VFS_LFS2),1) @@ -39,8 +37,6 @@ SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\ lfs2.c \ lfs2_util.c \ ) -else -CFLAGS_MOD += -DMICROPY_VFS_LFS2=0 $(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers endif diff --git a/extmod/font_petme128_8x8.h b/extmod/font_petme128_8x8.h index 632397dfe390a..0ee897d968908 100644 --- a/extmod/font_petme128_8x8.h +++ b/extmod/font_petme128_8x8.h @@ -1,108 +1,128 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George -// -// SPDX-License-Identifier: MIT - +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H #define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H static const uint8_t font_petme128_8x8[] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 32= - 0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00, // 33=! - 0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, // 34=" - 0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14, // 35=# - 0x00,0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00, // 36=$ - 0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, // 37=% - 0x00,0x32,0x7f,0x4d,0x4d,0x77,0x72,0x50, // 38=& - 0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00, // 39=' - 0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00, // 40=( - 0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00, // 41=) - 0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08, // 42=* - 0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00, // 43=+ - 0x00,0x00,0x80,0xe0,0x60,0x00,0x00,0x00, // 44=, - 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 45=- - 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // 46=. - 0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x02, // 47=/ - 0x00,0x3e,0x7f,0x49,0x45,0x7f,0x3e,0x00, // 48=0 - 0x00,0x40,0x44,0x7f,0x7f,0x40,0x40,0x00, // 49=1 - 0x00,0x62,0x73,0x51,0x49,0x4f,0x46,0x00, // 50=2 - 0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00, // 51=3 - 0x00,0x18,0x18,0x14,0x16,0x7f,0x7f,0x10, // 52=4 - 0x00,0x27,0x67,0x45,0x45,0x7d,0x39,0x00, // 53=5 - 0x00,0x3e,0x7f,0x49,0x49,0x7b,0x32,0x00, // 54=6 - 0x00,0x03,0x03,0x79,0x7d,0x07,0x03,0x00, // 55=7 - 0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00, // 56=8 - 0x00,0x26,0x6f,0x49,0x49,0x7f,0x3e,0x00, // 57=9 - 0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, // 58=: - 0x00,0x00,0x80,0xe4,0x64,0x00,0x00,0x00, // 59=; - 0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00, // 60=< - 0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // 61== - 0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00, // 62=> - 0x00,0x02,0x03,0x51,0x59,0x0f,0x06,0x00, // 63=? - 0x00,0x3e,0x7f,0x41,0x4d,0x4f,0x2e,0x00, // 64=@ - 0x00,0x7c,0x7e,0x0b,0x0b,0x7e,0x7c,0x00, // 65=A - 0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00, // 66=B - 0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00, // 67=C - 0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00, // 68=D - 0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00, // 69=E - 0x00,0x7f,0x7f,0x09,0x09,0x01,0x01,0x00, // 70=F - 0x00,0x3e,0x7f,0x41,0x49,0x7b,0x3a,0x00, // 71=G - 0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00, // 72=H - 0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00, // 73=I - 0x00,0x20,0x60,0x41,0x7f,0x3f,0x01,0x00, // 74=J - 0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00, // 75=K - 0x00,0x7f,0x7f,0x40,0x40,0x40,0x40,0x00, // 76=L - 0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f, // 77=M - 0x00,0x7f,0x7f,0x0e,0x1c,0x7f,0x7f,0x00, // 78=N - 0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00, // 79=O - 0x00,0x7f,0x7f,0x09,0x09,0x0f,0x06,0x00, // 80=P - 0x00,0x1e,0x3f,0x21,0x61,0x7f,0x5e,0x00, // 81=Q - 0x00,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00, // 82=R - 0x00,0x26,0x6f,0x49,0x49,0x7b,0x32,0x00, // 83=S - 0x00,0x01,0x01,0x7f,0x7f,0x01,0x01,0x00, // 84=T - 0x00,0x3f,0x7f,0x40,0x40,0x7f,0x3f,0x00, // 85=U - 0x00,0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00, // 86=V - 0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f, // 87=W - 0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00, // 88=X - 0x00,0x07,0x0f,0x78,0x78,0x0f,0x07,0x00, // 89=Y - 0x00,0x61,0x71,0x59,0x4d,0x47,0x43,0x00, // 90=Z - 0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00, // 91=[ - 0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0x40, // 92='\' - 0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00, // 93=] - 0x00,0x08,0x0c,0x06,0x06,0x0c,0x08,0x00, // 94=^ - 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, // 95=_ - 0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // 96=` - 0x00,0x20,0x74,0x54,0x54,0x7c,0x78,0x00, // 97=a - 0x00,0x7f,0x7f,0x44,0x44,0x7c,0x38,0x00, // 98=b - 0x00,0x38,0x7c,0x44,0x44,0x6c,0x28,0x00, // 99=c - 0x00,0x38,0x7c,0x44,0x44,0x7f,0x7f,0x00, // 100=d - 0x00,0x38,0x7c,0x54,0x54,0x5c,0x58,0x00, // 101=e - 0x00,0x08,0x7e,0x7f,0x09,0x03,0x02,0x00, // 102=f - 0x00,0x98,0xbc,0xa4,0xa4,0xfc,0x7c,0x00, // 103=g - 0x00,0x7f,0x7f,0x04,0x04,0x7c,0x78,0x00, // 104=h - 0x00,0x00,0x00,0x7d,0x7d,0x00,0x00,0x00, // 105=i - 0x00,0x40,0xc0,0x80,0x80,0xfd,0x7d,0x00, // 106=j - 0x00,0x7f,0x7f,0x30,0x38,0x6c,0x44,0x00, // 107=k - 0x00,0x00,0x41,0x7f,0x7f,0x40,0x00,0x00, // 108=l - 0x00,0x7c,0x7c,0x18,0x30,0x18,0x7c,0x7c, // 109=m - 0x00,0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00, // 110=n - 0x00,0x38,0x7c,0x44,0x44,0x7c,0x38,0x00, // 111=o - 0x00,0xfc,0xfc,0x24,0x24,0x3c,0x18,0x00, // 112=p - 0x00,0x18,0x3c,0x24,0x24,0xfc,0xfc,0x00, // 113=q - 0x00,0x7c,0x7c,0x04,0x04,0x0c,0x08,0x00, // 114=r - 0x00,0x48,0x5c,0x54,0x54,0x74,0x20,0x00, // 115=s - 0x04,0x04,0x3f,0x7f,0x44,0x64,0x20,0x00, // 116=t - 0x00,0x3c,0x7c,0x40,0x40,0x7c,0x3c,0x00, // 117=u - 0x00,0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00, // 118=v - 0x00,0x1c,0x7c,0x30,0x18,0x30,0x7c,0x1c, // 119=w - 0x00,0x44,0x6c,0x38,0x38,0x6c,0x44,0x00, // 120=x - 0x00,0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00, // 121=y - 0x00,0x44,0x64,0x74,0x5c,0x4c,0x44,0x00, // 122=z - 0x00,0x08,0x08,0x3e,0x77,0x41,0x41,0x00, // 123={ - 0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, // 124=| - 0x00,0x41,0x41,0x77,0x3e,0x08,0x08,0x00, // 125=} - 0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01, // 126=~ - 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, // 127 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32= + 0x00, 0x00, 0x00, 0x4f, 0x4f, 0x00, 0x00, 0x00, // 33=! + 0x00, 0x07, 0x07, 0x00, 0x00, 0x07, 0x07, 0x00, // 34=" + 0x14, 0x7f, 0x7f, 0x14, 0x14, 0x7f, 0x7f, 0x14, // 35=# + 0x00, 0x24, 0x2e, 0x6b, 0x6b, 0x3a, 0x12, 0x00, // 36=$ + 0x00, 0x63, 0x33, 0x18, 0x0c, 0x66, 0x63, 0x00, // 37=% + 0x00, 0x32, 0x7f, 0x4d, 0x4d, 0x77, 0x72, 0x50, // 38=& + 0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x01, 0x00, // 39=' + 0x00, 0x00, 0x1c, 0x3e, 0x63, 0x41, 0x00, 0x00, // 40=( + 0x00, 0x00, 0x41, 0x63, 0x3e, 0x1c, 0x00, 0x00, // 41=) + 0x08, 0x2a, 0x3e, 0x1c, 0x1c, 0x3e, 0x2a, 0x08, // 42=* + 0x00, 0x08, 0x08, 0x3e, 0x3e, 0x08, 0x08, 0x00, // 43=+ + 0x00, 0x00, 0x80, 0xe0, 0x60, 0x00, 0x00, 0x00, // 44=, + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, // 45=- + 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, // 46=. + 0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, // 47=/ + 0x00, 0x3e, 0x7f, 0x49, 0x45, 0x7f, 0x3e, 0x00, // 48=0 + 0x00, 0x40, 0x44, 0x7f, 0x7f, 0x40, 0x40, 0x00, // 49=1 + 0x00, 0x62, 0x73, 0x51, 0x49, 0x4f, 0x46, 0x00, // 50=2 + 0x00, 0x22, 0x63, 0x49, 0x49, 0x7f, 0x36, 0x00, // 51=3 + 0x00, 0x18, 0x18, 0x14, 0x16, 0x7f, 0x7f, 0x10, // 52=4 + 0x00, 0x27, 0x67, 0x45, 0x45, 0x7d, 0x39, 0x00, // 53=5 + 0x00, 0x3e, 0x7f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 54=6 + 0x00, 0x03, 0x03, 0x79, 0x7d, 0x07, 0x03, 0x00, // 55=7 + 0x00, 0x36, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 56=8 + 0x00, 0x26, 0x6f, 0x49, 0x49, 0x7f, 0x3e, 0x00, // 57=9 + 0x00, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, // 58=: + 0x00, 0x00, 0x80, 0xe4, 0x64, 0x00, 0x00, 0x00, // 59=; + 0x00, 0x08, 0x1c, 0x36, 0x63, 0x41, 0x41, 0x00, // 60=< + 0x00, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, // 61== + 0x00, 0x41, 0x41, 0x63, 0x36, 0x1c, 0x08, 0x00, // 62=> + 0x00, 0x02, 0x03, 0x51, 0x59, 0x0f, 0x06, 0x00, // 63=? + 0x00, 0x3e, 0x7f, 0x41, 0x4d, 0x4f, 0x2e, 0x00, // 64=@ + 0x00, 0x7c, 0x7e, 0x0b, 0x0b, 0x7e, 0x7c, 0x00, // 65=A + 0x00, 0x7f, 0x7f, 0x49, 0x49, 0x7f, 0x36, 0x00, // 66=B + 0x00, 0x3e, 0x7f, 0x41, 0x41, 0x63, 0x22, 0x00, // 67=C + 0x00, 0x7f, 0x7f, 0x41, 0x63, 0x3e, 0x1c, 0x00, // 68=D + 0x00, 0x7f, 0x7f, 0x49, 0x49, 0x41, 0x41, 0x00, // 69=E + 0x00, 0x7f, 0x7f, 0x09, 0x09, 0x01, 0x01, 0x00, // 70=F + 0x00, 0x3e, 0x7f, 0x41, 0x49, 0x7b, 0x3a, 0x00, // 71=G + 0x00, 0x7f, 0x7f, 0x08, 0x08, 0x7f, 0x7f, 0x00, // 72=H + 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x41, 0x00, 0x00, // 73=I + 0x00, 0x20, 0x60, 0x41, 0x7f, 0x3f, 0x01, 0x00, // 74=J + 0x00, 0x7f, 0x7f, 0x1c, 0x36, 0x63, 0x41, 0x00, // 75=K + 0x00, 0x7f, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, // 76=L + 0x00, 0x7f, 0x7f, 0x06, 0x0c, 0x06, 0x7f, 0x7f, // 77=M + 0x00, 0x7f, 0x7f, 0x0e, 0x1c, 0x7f, 0x7f, 0x00, // 78=N + 0x00, 0x3e, 0x7f, 0x41, 0x41, 0x7f, 0x3e, 0x00, // 79=O + 0x00, 0x7f, 0x7f, 0x09, 0x09, 0x0f, 0x06, 0x00, // 80=P + 0x00, 0x1e, 0x3f, 0x21, 0x61, 0x7f, 0x5e, 0x00, // 81=Q + 0x00, 0x7f, 0x7f, 0x19, 0x39, 0x6f, 0x46, 0x00, // 82=R + 0x00, 0x26, 0x6f, 0x49, 0x49, 0x7b, 0x32, 0x00, // 83=S + 0x00, 0x01, 0x01, 0x7f, 0x7f, 0x01, 0x01, 0x00, // 84=T + 0x00, 0x3f, 0x7f, 0x40, 0x40, 0x7f, 0x3f, 0x00, // 85=U + 0x00, 0x1f, 0x3f, 0x60, 0x60, 0x3f, 0x1f, 0x00, // 86=V + 0x00, 0x7f, 0x7f, 0x30, 0x18, 0x30, 0x7f, 0x7f, // 87=W + 0x00, 0x63, 0x77, 0x1c, 0x1c, 0x77, 0x63, 0x00, // 88=X + 0x00, 0x07, 0x0f, 0x78, 0x78, 0x0f, 0x07, 0x00, // 89=Y + 0x00, 0x61, 0x71, 0x59, 0x4d, 0x47, 0x43, 0x00, // 90=Z + 0x00, 0x00, 0x7f, 0x7f, 0x41, 0x41, 0x00, 0x00, // 91=[ + 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, // 92='\' + 0x00, 0x00, 0x41, 0x41, 0x7f, 0x7f, 0x00, 0x00, // 93=] + 0x00, 0x08, 0x0c, 0x06, 0x06, 0x0c, 0x08, 0x00, // 94=^ + 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, // 95=_ + 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00, // 96=` + 0x00, 0x20, 0x74, 0x54, 0x54, 0x7c, 0x78, 0x00, // 97=a + 0x00, 0x7f, 0x7f, 0x44, 0x44, 0x7c, 0x38, 0x00, // 98=b + 0x00, 0x38, 0x7c, 0x44, 0x44, 0x6c, 0x28, 0x00, // 99=c + 0x00, 0x38, 0x7c, 0x44, 0x44, 0x7f, 0x7f, 0x00, // 100=d + 0x00, 0x38, 0x7c, 0x54, 0x54, 0x5c, 0x58, 0x00, // 101=e + 0x00, 0x08, 0x7e, 0x7f, 0x09, 0x03, 0x02, 0x00, // 102=f + 0x00, 0x98, 0xbc, 0xa4, 0xa4, 0xfc, 0x7c, 0x00, // 103=g + 0x00, 0x7f, 0x7f, 0x04, 0x04, 0x7c, 0x78, 0x00, // 104=h + 0x00, 0x00, 0x00, 0x7d, 0x7d, 0x00, 0x00, 0x00, // 105=i + 0x00, 0x40, 0xc0, 0x80, 0x80, 0xfd, 0x7d, 0x00, // 106=j + 0x00, 0x7f, 0x7f, 0x30, 0x38, 0x6c, 0x44, 0x00, // 107=k + 0x00, 0x00, 0x41, 0x7f, 0x7f, 0x40, 0x00, 0x00, // 108=l + 0x00, 0x7c, 0x7c, 0x18, 0x30, 0x18, 0x7c, 0x7c, // 109=m + 0x00, 0x7c, 0x7c, 0x04, 0x04, 0x7c, 0x78, 0x00, // 110=n + 0x00, 0x38, 0x7c, 0x44, 0x44, 0x7c, 0x38, 0x00, // 111=o + 0x00, 0xfc, 0xfc, 0x24, 0x24, 0x3c, 0x18, 0x00, // 112=p + 0x00, 0x18, 0x3c, 0x24, 0x24, 0xfc, 0xfc, 0x00, // 113=q + 0x00, 0x7c, 0x7c, 0x04, 0x04, 0x0c, 0x08, 0x00, // 114=r + 0x00, 0x48, 0x5c, 0x54, 0x54, 0x74, 0x20, 0x00, // 115=s + 0x04, 0x04, 0x3f, 0x7f, 0x44, 0x64, 0x20, 0x00, // 116=t + 0x00, 0x3c, 0x7c, 0x40, 0x40, 0x7c, 0x3c, 0x00, // 117=u + 0x00, 0x1c, 0x3c, 0x60, 0x60, 0x3c, 0x1c, 0x00, // 118=v + 0x00, 0x1c, 0x7c, 0x30, 0x18, 0x30, 0x7c, 0x1c, // 119=w + 0x00, 0x44, 0x6c, 0x38, 0x38, 0x6c, 0x44, 0x00, // 120=x + 0x00, 0x9c, 0xbc, 0xa0, 0xa0, 0xfc, 0x7c, 0x00, // 121=y + 0x00, 0x44, 0x64, 0x74, 0x5c, 0x4c, 0x44, 0x00, // 122=z + 0x00, 0x08, 0x08, 0x3e, 0x77, 0x41, 0x41, 0x00, // 123={ + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, // 124=| + 0x00, 0x41, 0x41, 0x77, 0x3e, 0x08, 0x08, 0x00, // 125=} + 0x00, 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, // 126=~ + 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, // 127 }; #endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H diff --git a/py/gc_long_lived.h b/extmod/misc.h similarity index 59% rename from py/gc_long_lived.h rename to extmod/misc.h index 229bc73911c8f..a9392aa10b7b3 100644 --- a/py/gc_long_lived.h +++ b/extmod/misc.h @@ -3,7 +3,8 @@ * * The MIT License (MIT) * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC + * Copyright (c) 2014-2016 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,21 +24,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ +#ifndef MICROPY_INCLUDED_EXTMOD_MISC_H +#define MICROPY_INCLUDED_EXTMOD_MISC_H -// These helpers move MicroPython objects and their sub-objects to the long lived portion of the -// heap. +// This file contains cumulative declarations for extmod/ . -#ifndef MICROPY_INCLUDED_PY_GC_LONG_LIVED_H -#define MICROPY_INCLUDED_PY_GC_LONG_LIVED_H +#include +#include "py/runtime.h" -#include "py/objfun.h" -#include "py/objproperty.h" -#include "py/objstr.h" +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj); -mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_depth); -mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max_depth); -mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth); -mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str); -mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth); +#if MICROPY_PY_OS_DUPTERM +bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream); +void mp_uos_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached); +uintptr_t mp_uos_dupterm_poll(uintptr_t poll_flags); +int mp_uos_dupterm_rx_chr(void); +void mp_uos_dupterm_tx_strn(const char *str, size_t len); +void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc); +#else +#define mp_uos_dupterm_tx_strn(s, l) +#endif -#endif // MICROPY_INCLUDED_PY_GC_LONG_LIVED_H +#endif // MICROPY_INCLUDED_EXTMOD_MISC_H diff --git a/extmod/modbtree.c b/extmod/modbtree.c deleted file mode 100644 index 5f4b4696b4ff3..0000000000000 --- a/extmod/modbtree.c +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT - -#include -#include -#include // for declaration of global errno variable -#include - -#include "py/runtime.h" -#include "py/stream.h" - -#if MICROPY_PY_BTREE - -#include -#include <../../btree/btree.h> - -typedef struct _mp_obj_btree_t { - mp_obj_base_t base; - mp_obj_t stream; // retain a reference to prevent GC from reclaiming it - DB *db; - mp_obj_t start_key; - mp_obj_t end_key; - #define FLAG_END_KEY_INCL 1 - #define FLAG_DESC 2 - #define FLAG_ITER_TYPE_MASK 0xc0 - #define FLAG_ITER_KEYS 0x40 - #define FLAG_ITER_VALUES 0x80 - #define FLAG_ITER_ITEMS 0xc0 - byte flags; - byte next_flags; -} mp_obj_btree_t; - -#if !MICROPY_ENABLE_DYNRUNTIME -STATIC const mp_obj_type_t btree_type; -#endif - -#define CHECK_ERROR(res) \ - if (res == RET_ERROR) { \ - mp_raise_OSError(errno); \ - } - -void __dbpanic(DB *db) { - mp_printf(&mp_plat_print, "__dbpanic(%p)\n", db); -} - -STATIC mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) { - mp_obj_btree_t *o = m_new_obj(mp_obj_btree_t); - o->base.type = (mp_obj_type_t *)&btree_type; - o->stream = stream; - o->db = db; - o->start_key = mp_const_none; - o->end_key = mp_const_none; - o->next_flags = 0; - return o; -} - -STATIC void btree_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - (void)kind; - mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "", self->db); -} - -STATIC mp_obj_t btree_flush(mp_obj_t self_in) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(__bt_sync(self->db, 0)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(btree_flush_obj, btree_flush); - -STATIC mp_obj_t btree_close(mp_obj_t self_in) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(__bt_close(self->db)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(btree_close_obj, btree_close); - -STATIC mp_obj_t btree_put(size_t n_args, const mp_obj_t *args) { - (void)n_args; - mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); - DBT key, val; - key.data = (void *)mp_obj_str_get_data(args[1], &key.size); - val.data = (void *)mp_obj_str_get_data(args[2], &val.size); - return MP_OBJ_NEW_SMALL_INT(__bt_put(self->db, &key, &val, 0)); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_put_obj, 3, 4, btree_put); - -STATIC mp_obj_t btree_get(size_t n_args, const mp_obj_t *args) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); - DBT key, val; - key.data = (void *)mp_obj_str_get_data(args[1], &key.size); - int res = __bt_get(self->db, &key, &val, 0); - if (res == RET_SPECIAL) { - if (n_args > 2) { - return args[2]; - } else { - return mp_const_none; - } - } - CHECK_ERROR(res); - return mp_obj_new_bytes(val.data, val.size); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_get_obj, 2, 3, btree_get); - -STATIC mp_obj_t btree_seq(size_t n_args, const mp_obj_t *args) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); - int flags = MP_OBJ_SMALL_INT_VALUE(args[1]); - DBT key, val; - if (n_args > 2) { - key.data = (void *)mp_obj_str_get_data(args[2], &key.size); - } - - int res = __bt_seq(self->db, &key, &val, flags); - CHECK_ERROR(res); - if (res == RET_SPECIAL) { - return mp_const_none; - } - - mp_obj_t pair_o = mp_obj_new_tuple(2, NULL); - mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(pair_o); - pair->items[0] = mp_obj_new_bytes(key.data, key.size); - pair->items[1] = mp_obj_new_bytes(val.data, val.size); - return pair_o; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_seq_obj, 2, 4, btree_seq); - -STATIC mp_obj_t btree_init_iter(size_t n_args, const mp_obj_t *args, byte type) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(args[0]); - self->next_flags = type; - self->start_key = mp_const_none; - self->end_key = mp_const_none; - if (n_args > 1) { - self->start_key = args[1]; - if (n_args > 2) { - self->end_key = args[2]; - if (n_args > 3) { - self->next_flags = type | MP_OBJ_SMALL_INT_VALUE(args[3]); - } - } - } - return args[0]; -} - -STATIC mp_obj_t btree_keys(size_t n_args, const mp_obj_t *args) { - return btree_init_iter(n_args, args, FLAG_ITER_KEYS); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_keys_obj, 1, 4, btree_keys); - -STATIC mp_obj_t btree_values(size_t n_args, const mp_obj_t *args) { - return btree_init_iter(n_args, args, FLAG_ITER_VALUES); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_values_obj, 1, 4, btree_values); - -STATIC mp_obj_t btree_items(size_t n_args, const mp_obj_t *args) { - return btree_init_iter(n_args, args, FLAG_ITER_ITEMS); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(btree_items_obj, 1, 4, btree_items); - -STATIC mp_obj_t btree_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { - (void)iter_buf; - mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); - if (self->next_flags != 0) { - // If we're called immediately after keys(), values(), or items(), - // use their setup for iteration. - self->flags = self->next_flags; - self->next_flags = 0; - } else { - // Otherwise, iterate over all keys. - self->flags = FLAG_ITER_KEYS; - self->start_key = mp_const_none; - self->end_key = mp_const_none; - } - - return self_in; -} - -STATIC mp_obj_t btree_iternext(mp_obj_t self_in) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); - DBT key, val; - int res; - bool desc = self->flags & FLAG_DESC; - if (self->start_key != MP_OBJ_NULL) { - int flags = R_FIRST; - if (self->start_key != mp_const_none) { - key.data = (void *)mp_obj_str_get_data(self->start_key, &key.size); - flags = R_CURSOR; - } else if (desc) { - flags = R_LAST; - } - res = __bt_seq(self->db, &key, &val, flags); - self->start_key = MP_OBJ_NULL; - } else { - res = __bt_seq(self->db, &key, &val, desc ? R_PREV : R_NEXT); - } - - if (res == RET_SPECIAL) { - return MP_OBJ_STOP_ITERATION; - } - CHECK_ERROR(res); - - if (self->end_key != mp_const_none) { - DBT end_key; - end_key.data = (void *)mp_obj_str_get_data(self->end_key, &end_key.size); - BTREE *t = self->db->internal; - int cmp = t->bt_cmp(&key, &end_key); - if (desc) { - cmp = -cmp; - } - if (self->flags & FLAG_END_KEY_INCL) { - cmp--; - } - if (cmp >= 0) { - self->end_key = MP_OBJ_NULL; - return MP_OBJ_STOP_ITERATION; - } - } - - switch (self->flags & FLAG_ITER_TYPE_MASK) { - case FLAG_ITER_KEYS: - return mp_obj_new_bytes(key.data, key.size); - case FLAG_ITER_VALUES: - return mp_obj_new_bytes(val.data, val.size); - default: { - mp_obj_t pair_o = mp_obj_new_tuple(2, NULL); - mp_obj_tuple_t *pair = MP_OBJ_TO_PTR(pair_o); - pair->items[0] = mp_obj_new_bytes(key.data, key.size); - pair->items[1] = mp_obj_new_bytes(val.data, val.size); - return pair_o; - } - } -} - -STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { - mp_obj_btree_t *self = mp_obj_cast_to_native_base(self_in, &btree_type); - if (value == MP_OBJ_NULL) { - // delete - DBT key; - key.data = (void *)mp_obj_str_get_data(index, &key.size); - int res = __bt_delete(self->db, &key, 0); - if (res == RET_SPECIAL) { - mp_raise_type(&mp_type_KeyError); - } - CHECK_ERROR(res); - return mp_const_none; - } else if (value == MP_OBJ_SENTINEL) { - // load - DBT key, val; - key.data = (void *)mp_obj_str_get_data(index, &key.size); - int res = __bt_get(self->db, &key, &val, 0); - if (res == RET_SPECIAL) { - mp_raise_type(&mp_type_KeyError); - } - CHECK_ERROR(res); - return mp_obj_new_bytes(val.data, val.size); - } else { - // store - DBT key, val; - key.data = (void *)mp_obj_str_get_data(index, &key.size); - val.data = (void *)mp_obj_str_get_data(value, &val.size); - int res = __bt_put(self->db, &key, &val, 0); - CHECK_ERROR(res); - return mp_const_none; - } -} - -STATIC mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(lhs_in); - switch (op) { - case MP_BINARY_OP_CONTAINS: { - DBT key, val; - key.data = (void *)mp_obj_str_get_data(rhs_in, &key.size); - int res = __bt_get(self->db, &key, &val, 0); - CHECK_ERROR(res); - return mp_obj_new_bool(res != RET_SPECIAL); - } - default: - // op not supported - return MP_OBJ_NULL; - } -} - -#if !MICROPY_ENABLE_DYNRUNTIME -STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&btree_close_obj) }, - { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&btree_flush_obj) }, - { MP_ROM_QSTR(MP_QSTR_get), MP_ROM_PTR(&btree_get_obj) }, - { MP_ROM_QSTR(MP_QSTR_put), MP_ROM_PTR(&btree_put_obj) }, - { MP_ROM_QSTR(MP_QSTR_seq), MP_ROM_PTR(&btree_seq_obj) }, - { MP_ROM_QSTR(MP_QSTR_keys), MP_ROM_PTR(&btree_keys_obj) }, - { MP_ROM_QSTR(MP_QSTR_values), MP_ROM_PTR(&btree_values_obj) }, - { MP_ROM_QSTR(MP_QSTR_items), MP_ROM_PTR(&btree_items_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table); - -STATIC const mp_obj_type_t btree_type = { - { &mp_type_type }, - // Save on qstr's, reuse same as for module - .flags = MP_TYPE_FLAG_EXTENDED, - .name = MP_QSTR_btree, - .print = btree_print, - .locals_dict = (void *)&btree_locals_dict, - MP_TYPE_EXTENDED_FIELDS( - .getiter = btree_getiter, - .iternext = btree_iternext, - .binary_op = btree_binary_op, - .subscr = btree_subscr, - ), -}; -#endif - -STATIC const FILEVTABLE btree_stream_fvtable = { - mp_stream_posix_read, - mp_stream_posix_write, - mp_stream_posix_lseek, - mp_stream_posix_fsync -}; - -#if !MICROPY_ENABLE_DYNRUNTIME -STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_flags, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_cachesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_pagesize, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_minkeypage, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - }; - - // Make sure we got a stream object - mp_get_stream_raise(pos_args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); - - struct { - mp_arg_val_t flags; - mp_arg_val_t cachesize; - mp_arg_val_t pagesize; - mp_arg_val_t minkeypage; - } args; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, - MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); - BTREEINFO openinfo = {0}; - openinfo.flags = args.flags.u_int; - openinfo.cachesize = args.cachesize.u_int; - openinfo.psize = args.pagesize.u_int; - openinfo.minkeypage = args.minkeypage.u_int; - - DB *db = __bt_open(MP_OBJ_TO_PTR(pos_args[0]), &btree_stream_fvtable, &openinfo, /*dflags*/ 0); - if (db == NULL) { - mp_raise_OSError(errno); - } - return MP_OBJ_FROM_PTR(btree_new(db, pos_args[0])); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_btree_open_obj, 1, mod_btree_open); - -STATIC const mp_rom_map_elem_t mp_module_btree_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_btree) }, - { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mod_btree_open_obj) }, - { MP_ROM_QSTR(MP_QSTR_INCL), MP_ROM_INT(FLAG_END_KEY_INCL) }, - { MP_ROM_QSTR(MP_QSTR_DESC), MP_ROM_INT(FLAG_DESC) }, -}; - -STATIC MP_DEFINE_CONST_DICT(mp_module_btree_globals, mp_module_btree_globals_table); - -const mp_obj_module_t mp_module_btree = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&mp_module_btree_globals, -}; -#endif - -#endif // MICROPY_PY_BTREE diff --git a/extmod/modframebuf.c b/extmod/modframebuf.c deleted file mode 100644 index a90f00c347afc..0000000000000 --- a/extmod/modframebuf.c +++ /dev/null @@ -1,667 +0,0 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George -// -// SPDX-License-Identifier: MIT - -#include -#include - -#include "py/runtime.h" -#include "py/objtype.h" -#include "py/proto.h" - -#if MICROPY_PY_FRAMEBUF - -#include "font_petme128_8x8.h" - -typedef struct _mp_obj_framebuf_t { - mp_obj_base_t base; - mp_obj_t buf_obj; // need to store this to prevent GC from reclaiming buf - void *buf; - uint16_t width, height, stride; - uint8_t format; -} mp_obj_framebuf_t; - -#if !MICROPY_ENABLE_DYNRUNTIME -STATIC const mp_obj_type_t mp_type_framebuf; -#endif - -typedef void (*setpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, uint32_t); -typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int); -typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, unsigned int, unsigned int, uint32_t); - -typedef struct _mp_framebuf_p_t { - setpixel_t setpixel; - getpixel_t getpixel; - fill_rect_t fill_rect; -} mp_framebuf_p_t; - -// constants for formats -#define FRAMEBUF_MVLSB (0) -#define FRAMEBUF_RGB565 (1) -#define FRAMEBUF_GS2_HMSB (5) -#define FRAMEBUF_GS4_HMSB (2) -#define FRAMEBUF_GS8 (6) -#define FRAMEBUF_MHLSB (3) -#define FRAMEBUF_MHMSB (4) - -// Functions for MHLSB and MHMSB - -STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { - size_t index = (x + y * fb->stride) >> 3; - unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07); - ((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset); -} - -STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { - size_t index = (x + y * fb->stride) >> 3; - unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07); - return (((uint8_t *)fb->buf)[index] >> (offset)) & 0x01; -} - -STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) { - unsigned int reverse = fb->format == FRAMEBUF_MHMSB; - unsigned int advance = fb->stride >> 3; - while (w--) { - uint8_t *b = &((uint8_t *)fb->buf)[(x >> 3) + y * advance]; - unsigned int offset = reverse ? x & 7 : 7 - (x & 7); - for (unsigned int hh = h; hh; --hh) { - *b = (*b & ~(0x01 << offset)) | ((col != 0) << offset); - b += advance; - } - ++x; - } -} - -// Functions for MVLSB format - -STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { - size_t index = (y >> 3) * fb->stride + x; - uint8_t offset = y & 0x07; - ((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset); -} - -STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { - return (((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x] >> (y & 0x07)) & 0x01; -} - -STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) { - while (h--) { - uint8_t *b = &((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x]; - uint8_t offset = y & 0x07; - for (unsigned int ww = w; ww; --ww) { - *b = (*b & ~(0x01 << offset)) | ((col != 0) << offset); - ++b; - } - ++y; - } -} - -// Functions for RGB565 format - -STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { - ((uint16_t *)fb->buf)[x + y * fb->stride] = col; -} - -STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { - return ((uint16_t *)fb->buf)[x + y * fb->stride]; -} - -STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) { - uint16_t *b = &((uint16_t *)fb->buf)[x + y * fb->stride]; - while (h--) { - for (unsigned int ww = w; ww; --ww) { - *b++ = col; - } - b += fb->stride - w; - } -} - -// Functions for GS2_HMSB format - -STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { - uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2]; - uint8_t shift = (x & 0x3) << 1; - uint8_t mask = 0x3 << shift; - uint8_t color = (col & 0x3) << shift; - *pixel = color | (*pixel & (~mask)); -} - -STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { - uint8_t pixel = ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2]; - uint8_t shift = (x & 0x3) << 1; - return (pixel >> shift) & 0x3; -} - -STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) { - for (unsigned int xx = x; xx < x + w; xx++) { - for (unsigned int yy = y; yy < y + h; yy++) { - gs2_hmsb_setpixel(fb, xx, yy, col); - } - } -} - -// Functions for GS4_HMSB format - -STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { - uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1]; - - if (x % 2) { - *pixel = ((uint8_t)col & 0x0f) | (*pixel & 0xf0); - } else { - *pixel = ((uint8_t)col << 4) | (*pixel & 0x0f); - } -} - -STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { - if (x % 2) { - return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f; - } - - return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] >> 4; -} - -STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) { - col &= 0x0f; - uint8_t *pixel_pair = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1]; - uint8_t col_shifted_left = col << 4; - uint8_t col_pixel_pair = col_shifted_left | col; - unsigned int pixel_count_till_next_line = (fb->stride - w) >> 1; - bool odd_x = (x % 2 == 1); - - while (h--) { - unsigned int ww = w; - - if (odd_x && ww > 0) { - *pixel_pair = (*pixel_pair & 0xf0) | col; - pixel_pair++; - ww--; - } - - memset(pixel_pair, col_pixel_pair, ww >> 1); - pixel_pair += ww >> 1; - - if (ww % 2) { - *pixel_pair = col_shifted_left | (*pixel_pair & 0x0f); - if (!odd_x) { - pixel_pair++; - } - } - - pixel_pair += pixel_count_till_next_line; - } -} - -// Functions for GS8 format - -STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { - uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)]; - *pixel = col & 0xff; -} - -STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { - return ((uint8_t *)fb->buf)[(x + y * fb->stride)]; -} - -STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) { - uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)]; - while (h--) { - memset(pixel, col, w); - pixel += fb->stride; - } -} - -STATIC const mp_framebuf_p_t formats[] = { - [FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect}, - [FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect}, - [FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect}, - [FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect}, - [FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect}, - [FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect}, - [FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect}, -}; - -static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) { - formats[fb->format].setpixel(fb, x, y, col); -} - -static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) { - return formats[fb->format].getpixel(fb, x, y); -} - -STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) { - if (h < 1 || w < 1 || x + w <= 0 || y + h <= 0 || y >= fb->height || x >= fb->width) { - // No operation needed. - return; - } - - // clip to the framebuffer - int xend = MIN(fb->width, x + w); - int yend = MIN(fb->height, y + h); - x = MAX(x, 0); - y = MAX(y, 0); - - formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col); -} - -STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 4, 5, false); - - mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t); - o->base.type = type; - o->buf_obj = args[0]; - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE); - o->buf = bufinfo.buf; - - o->width = mp_obj_get_int(args[1]); - o->height = mp_obj_get_int(args[2]); - o->format = mp_obj_get_int(args[3]); - if (n_args >= 5) { - o->stride = mp_obj_get_int(args[4]); - } else { - o->stride = o->width; - } - - switch (o->format) { - case FRAMEBUF_MVLSB: - case FRAMEBUF_RGB565: - break; - case FRAMEBUF_MHLSB: - case FRAMEBUF_MHMSB: - o->stride = (o->stride + 7) & ~7; - break; - case FRAMEBUF_GS2_HMSB: - o->stride = (o->stride + 3) & ~3; - break; - case FRAMEBUF_GS4_HMSB: - o->stride = (o->stride + 1) & ~1; - break; - case FRAMEBUF_GS8: - break; - default: - mp_raise_ValueError(MP_ERROR_TEXT("invalid format")); - } - - return MP_OBJ_FROM_PTR(o); -} - -#if !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME) -STATIC const mp_obj_type_t mp_type_framebuf; -#endif - -// Helper to ensure we have the native super class instead of a subclass. -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); -} - -STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { - (void)flags; - mp_obj_framebuf_t *self = native_framebuf(self_in); - bufinfo->buf = self->buf; - bufinfo->len = self->stride * self->height * (self->format == FRAMEBUF_RGB565 ? 2 : 1); - bufinfo->typecode = 'B'; // view framebuf as bytes - return 0; -} - -STATIC mp_obj_t framebuf_fill(mp_obj_t self_in, mp_obj_t col_in) { - mp_obj_framebuf_t *self = native_framebuf(self_in); - mp_int_t col = mp_obj_get_int(col_in); - formats[self->format].fill_rect(self, 0, 0, self->width, self->height, col); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(framebuf_fill_obj, framebuf_fill); - -STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = native_framebuf(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t width = mp_obj_get_int(args[3]); - mp_int_t height = mp_obj_get_int(args[4]); - mp_int_t col = mp_obj_get_int(args[5]); - - fill_rect(self, x, y, width, height, col); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect); - -STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) { - mp_obj_framebuf_t *self = native_framebuf(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - if (0 <= x && x < self->width && 0 <= y && y < self->height) { - if (n_args == 3) { - // get - return MP_OBJ_NEW_SMALL_INT(getpixel(self, x, y)); - } else { - // set - setpixel(self, x, y, mp_obj_get_int(args[3])); - } - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pixel); - -STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = native_framebuf(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t w = mp_obj_get_int(args[3]); - mp_int_t col = mp_obj_get_int(args[4]); - - fill_rect(self, x, y, w, 1, col); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hline); - -STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = native_framebuf(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t h = mp_obj_get_int(args[3]); - mp_int_t col = mp_obj_get_int(args[4]); - - fill_rect(self, x, y, 1, h, col); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vline); - -STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = native_framebuf(args[0]); - mp_int_t x = mp_obj_get_int(args[1]); - mp_int_t y = mp_obj_get_int(args[2]); - mp_int_t w = mp_obj_get_int(args[3]); - mp_int_t h = mp_obj_get_int(args[4]); - mp_int_t col = mp_obj_get_int(args[5]); - - fill_rect(self, x, y, w, 1, col); - fill_rect(self, x, y + h - 1, w, 1, col); - fill_rect(self, x, y, 1, h, col); - fill_rect(self, x + w - 1, y, 1, h, col); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rect); - -STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) { - (void)n_args; - - mp_obj_framebuf_t *self = native_framebuf(args[0]); - mp_int_t x1 = mp_obj_get_int(args[1]); - mp_int_t y1 = mp_obj_get_int(args[2]); - mp_int_t x2 = mp_obj_get_int(args[3]); - mp_int_t y2 = mp_obj_get_int(args[4]); - mp_int_t col = mp_obj_get_int(args[5]); - - mp_int_t dx = x2 - x1; - mp_int_t sx; - if (dx > 0) { - sx = 1; - } else { - dx = -dx; - sx = -1; - } - - mp_int_t dy = y2 - y1; - mp_int_t sy; - if (dy > 0) { - sy = 1; - } else { - dy = -dy; - sy = -1; - } - - bool steep; - if (dy > dx) { - mp_int_t temp; - temp = x1; - x1 = y1; - y1 = temp; - temp = dx; - dx = dy; - dy = temp; - temp = sx; - sx = sy; - sy = temp; - steep = true; - } else { - steep = false; - } - - mp_int_t e = 2 * dy - dx; - for (mp_int_t i = 0; i < dx; ++i) { - if (steep) { - if (0 <= y1 && y1 < self->width && 0 <= x1 && x1 < self->height) { - setpixel(self, y1, x1, col); - } - } else { - if (0 <= x1 && x1 < self->width && 0 <= y1 && y1 < self->height) { - setpixel(self, x1, y1, col); - } - } - while (e >= 0) { - y1 += sy; - e -= 2 * dx; - } - x1 += sx; - e += 2 * dy; - } - - if (0 <= x2 && x2 < self->width && 0 <= y2 && y2 < self->height) { - setpixel(self, x2, y2, col); - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line); - -STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) { - mp_obj_framebuf_t *self = native_framebuf(args[0]); - mp_obj_framebuf_t *source = native_framebuf(args[1]); - mp_int_t x = mp_obj_get_int(args[2]); - mp_int_t y = mp_obj_get_int(args[3]); - mp_int_t key = -1; - if (n_args > 4) { - key = mp_obj_get_int(args[4]); - } - mp_obj_framebuf_t *palette = NULL; - if (n_args > 5 && args[5] != mp_const_none) { - palette = MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(args[5], MP_OBJ_FROM_PTR(&mp_type_framebuf))); - } - - if ( - (x >= self->width) || - (y >= self->height) || - (-x >= source->width) || - (-y >= source->height) - ) { - // Out of bounds, no-op. - return mp_const_none; - } - - // Clip. - int x0 = MAX(0, x); - int y0 = MAX(0, y); - int x1 = MAX(0, -x); - int y1 = MAX(0, -y); - int x0end = MIN(self->width, x + source->width); - int y0end = MIN(self->height, y + source->height); - - for (; y0 < y0end; ++y0) { - int cx1 = x1; - for (int cx0 = x0; cx0 < x0end; ++cx0) { - uint32_t col = getpixel(source, cx1, y1); - if (palette) { - col = getpixel(palette, col, 0); - } - if (col != (uint32_t)key) { - setpixel(self, cx0, y0, col); - } - ++cx1; - } - ++y1; - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 6, framebuf_blit); - -STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) { - mp_obj_framebuf_t *self = native_framebuf(self_in); - mp_int_t xstep = mp_obj_get_int(xstep_in); - mp_int_t ystep = mp_obj_get_int(ystep_in); - int sx, y, xend, yend, dx, dy; - if (xstep < 0) { - sx = 0; - xend = self->width + xstep; - dx = 1; - } else { - sx = self->width - 1; - xend = xstep - 1; - dx = -1; - } - if (ystep < 0) { - y = 0; - yend = self->height + ystep; - dy = 1; - } else { - y = self->height - 1; - yend = ystep - 1; - dy = -1; - } - for (; y != yend; y += dy) { - for (int x = sx; x != xend; x += dx) { - setpixel(self, x, y, getpixel(self, x - xstep, y - ystep)); - } - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf_scroll_obj, framebuf_scroll); - -STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) { - // extract arguments - mp_obj_framebuf_t *self = native_framebuf(args[0]); - const char *str = mp_obj_str_get_str(args[1]); - mp_int_t x0 = mp_obj_get_int(args[2]); - mp_int_t y0 = mp_obj_get_int(args[3]); - mp_int_t col = 1; - if (n_args >= 5) { - col = mp_obj_get_int(args[4]); - } - - // loop over chars - for (; *str; ++str) { - // get char and make sure its in range of font - int chr = *(uint8_t *)str; - if (chr < 32 || chr > 127) { - chr = 127; - } - // get char data - const uint8_t *chr_data = &font_petme128_8x8[(chr - 32) * 8]; - // loop over char data - for (int j = 0; j < 8; j++, x0++) { - if (0 <= x0 && x0 < self->width) { // clip x - uint vline_data = chr_data[j]; // each byte is a column of 8 pixels, LSB at top - for (int y = y0; vline_data; vline_data >>= 1, y++) { // scan over vertical column - if (vline_data & 1) { // only draw if pixel set - if (0 <= y && y < self->height) { // clip y - setpixel(self, x0, y, col); - } - } - } - } - } - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 5, framebuf_text); - -#if !MICROPY_ENABLE_DYNRUNTIME -STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&framebuf_fill_obj) }, - { MP_ROM_QSTR(MP_QSTR_fill_rect), MP_ROM_PTR(&framebuf_fill_rect_obj) }, - { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&framebuf_pixel_obj) }, - { MP_ROM_QSTR(MP_QSTR_hline), MP_ROM_PTR(&framebuf_hline_obj) }, - { MP_ROM_QSTR(MP_QSTR_vline), MP_ROM_PTR(&framebuf_vline_obj) }, - { MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&framebuf_rect_obj) }, - { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&framebuf_line_obj) }, - { MP_ROM_QSTR(MP_QSTR_blit), MP_ROM_PTR(&framebuf_blit_obj) }, - { MP_ROM_QSTR(MP_QSTR_scroll), MP_ROM_PTR(&framebuf_scroll_obj) }, - { MP_ROM_QSTR(MP_QSTR_text), MP_ROM_PTR(&framebuf_text_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table); - -STATIC const mp_obj_type_t mp_type_framebuf = { - { &mp_type_type }, - .flags = MP_TYPE_FLAG_EXTENDED, - .name = MP_QSTR_FrameBuffer, - .make_new = framebuf_make_new, - .locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict, - MP_TYPE_EXTENDED_FIELDS( - .buffer_p = { .get_buffer = framebuf_get_buffer }, - ), -}; -#endif - -// this factory function is provided for backwards compatibility with old FrameBuffer1 class -STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args) { - mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t); - o->base.type = (mp_obj_type_t *)&mp_type_framebuf; - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_WRITE); - o->buf = bufinfo.buf; - - o->width = mp_obj_get_int(args[1]); - o->height = mp_obj_get_int(args[2]); - o->format = FRAMEBUF_MVLSB; - if (n_args >= 4) { - o->stride = mp_obj_get_int(args[3]); - } else { - o->stride = o->width; - } - - return MP_OBJ_FROM_PTR(o); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(legacy_framebuffer1_obj, 3, 4, legacy_framebuffer1); - -#if !MICROPY_ENABLE_DYNRUNTIME -STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_framebuf) }, - { MP_ROM_QSTR(MP_QSTR_FrameBuffer), MP_ROM_PTR(&mp_type_framebuf) }, - { MP_ROM_QSTR(MP_QSTR_FrameBuffer1), MP_ROM_PTR(&legacy_framebuffer1_obj) }, - { MP_ROM_QSTR(MP_QSTR_MVLSB), MP_ROM_INT(FRAMEBUF_MVLSB) }, - { MP_ROM_QSTR(MP_QSTR_MONO_VLSB), MP_ROM_INT(FRAMEBUF_MVLSB) }, - { MP_ROM_QSTR(MP_QSTR_RGB565), MP_ROM_INT(FRAMEBUF_RGB565) }, - { MP_ROM_QSTR(MP_QSTR_GS2_HMSB), MP_ROM_INT(FRAMEBUF_GS2_HMSB) }, - { MP_ROM_QSTR(MP_QSTR_GS4_HMSB), MP_ROM_INT(FRAMEBUF_GS4_HMSB) }, - { MP_ROM_QSTR(MP_QSTR_GS8), MP_ROM_INT(FRAMEBUF_GS8) }, - { MP_ROM_QSTR(MP_QSTR_MONO_HLSB), MP_ROM_INT(FRAMEBUF_MHLSB) }, - { MP_ROM_QSTR(MP_QSTR_MONO_HMSB), MP_ROM_INT(FRAMEBUF_MHMSB) }, -}; - -STATIC MP_DEFINE_CONST_DICT(framebuf_module_globals, framebuf_module_globals_table); - -const mp_obj_module_t mp_module_framebuf = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&framebuf_module_globals, -}; -#endif - -#endif // MICROPY_PY_FRAMEBUF diff --git a/extmod/modonewire.c b/extmod/modonewire.c deleted file mode 100644 index ba7405fbae661..0000000000000 --- a/extmod/modonewire.c +++ /dev/null @@ -1,145 +0,0 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Damien P. George -// -// SPDX-License-Identifier: MIT - -#include -#include - -#include "py/obj.h" -#include "py/mphal.h" - -#if MICROPY_PY_ONEWIRE - -/******************************************************************************/ -// Low-level 1-Wire routines - -#define TIMING_RESET1 (480) -#define TIMING_RESET2 (70) -#define TIMING_RESET3 (410) -#define TIMING_READ1 (5) -#define TIMING_READ2 (5) -#define TIMING_READ3 (40) -#define TIMING_WRITE1 (10) -#define TIMING_WRITE2 (50) -#define TIMING_WRITE3 (10) - -STATIC int onewire_bus_reset(mp_hal_pin_obj_t pin) { - mp_hal_pin_od_low(pin); - mp_hal_delay_us(TIMING_RESET1); - uint32_t i = mp_hal_quiet_timing_enter(); - mp_hal_pin_od_high(pin); - mp_hal_delay_us_fast(TIMING_RESET2); - int status = !mp_hal_pin_read(pin); - mp_hal_quiet_timing_exit(i); - mp_hal_delay_us(TIMING_RESET3); - return status; -} - -STATIC int onewire_bus_readbit(mp_hal_pin_obj_t pin) { - mp_hal_pin_od_high(pin); - uint32_t i = mp_hal_quiet_timing_enter(); - mp_hal_pin_od_low(pin); - mp_hal_delay_us_fast(TIMING_READ1); - mp_hal_pin_od_high(pin); - mp_hal_delay_us_fast(TIMING_READ2); - int value = mp_hal_pin_read(pin); - mp_hal_quiet_timing_exit(i); - mp_hal_delay_us_fast(TIMING_READ3); - return value; -} - -STATIC void onewire_bus_writebit(mp_hal_pin_obj_t pin, int value) { - uint32_t i = mp_hal_quiet_timing_enter(); - mp_hal_pin_od_low(pin); - mp_hal_delay_us_fast(TIMING_WRITE1); - if (value) { - mp_hal_pin_od_high(pin); - } - mp_hal_delay_us_fast(TIMING_WRITE2); - mp_hal_pin_od_high(pin); - mp_hal_delay_us_fast(TIMING_WRITE3); - mp_hal_quiet_timing_exit(i); -} - -/******************************************************************************/ -// MicroPython bindings - -STATIC mp_obj_t onewire_reset(mp_obj_t pin_in) { - return mp_obj_new_bool(onewire_bus_reset(mp_hal_get_pin_obj(pin_in))); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_reset_obj, onewire_reset); - -STATIC mp_obj_t onewire_readbit(mp_obj_t pin_in) { - return MP_OBJ_NEW_SMALL_INT(onewire_bus_readbit(mp_hal_get_pin_obj(pin_in))); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_readbit_obj, onewire_readbit); - -STATIC mp_obj_t onewire_readbyte(mp_obj_t pin_in) { - mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in); - uint8_t value = 0; - for (int i = 0; i < 8; ++i) { - value |= onewire_bus_readbit(pin) << i; - } - return MP_OBJ_NEW_SMALL_INT(value); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_readbyte_obj, onewire_readbyte); - -STATIC mp_obj_t onewire_writebit(mp_obj_t pin_in, mp_obj_t value_in) { - onewire_bus_writebit(mp_hal_get_pin_obj(pin_in), mp_obj_get_int(value_in)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(onewire_writebit_obj, onewire_writebit); - -STATIC mp_obj_t onewire_writebyte(mp_obj_t pin_in, mp_obj_t value_in) { - mp_hal_pin_obj_t pin = mp_hal_get_pin_obj(pin_in); - int value = mp_obj_get_int(value_in); - for (int i = 0; i < 8; ++i) { - onewire_bus_writebit(pin, value & 1); - value >>= 1; - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(onewire_writebyte_obj, onewire_writebyte); - -STATIC mp_obj_t onewire_crc8(mp_obj_t data) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); - uint8_t crc = 0; - for (size_t i = 0; i < bufinfo.len; ++i) { - uint8_t byte = ((uint8_t *)bufinfo.buf)[i]; - for (int b = 0; b < 8; ++b) { - uint8_t fb_bit = (crc ^ byte) & 0x01; - if (fb_bit == 0x01) { - crc = crc ^ 0x18; - } - crc = (crc >> 1) & 0x7f; - if (fb_bit == 0x01) { - crc = crc | 0x80; - } - byte = byte >> 1; - } - } - return MP_OBJ_NEW_SMALL_INT(crc); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(onewire_crc8_obj, onewire_crc8); - -STATIC const mp_rom_map_elem_t onewire_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_onewire) }, - - { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&onewire_reset_obj) }, - { MP_ROM_QSTR(MP_QSTR_readbit), MP_ROM_PTR(&onewire_readbit_obj) }, - { MP_ROM_QSTR(MP_QSTR_readbyte), MP_ROM_PTR(&onewire_readbyte_obj) }, - { MP_ROM_QSTR(MP_QSTR_writebit), MP_ROM_PTR(&onewire_writebit_obj) }, - { MP_ROM_QSTR(MP_QSTR_writebyte), MP_ROM_PTR(&onewire_writebyte_obj) }, - { MP_ROM_QSTR(MP_QSTR_crc8), MP_ROM_PTR(&onewire_crc8_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(onewire_module_globals, onewire_module_globals_table); - -const mp_obj_module_t mp_module_onewire = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&onewire_module_globals, -}; - -#endif // MICROPY_PY_ONEWIRE diff --git a/extmod/moduasyncio.c b/extmod/moduasyncio.c index 1e1c5de7e7265..2ba8efb1fe93e 100644 --- a/extmod/moduasyncio.c +++ b/extmod/moduasyncio.c @@ -29,14 +29,14 @@ #include "py/pairheap.h" #include "py/mphal.h" +#if MICROPY_PY_UASYNCIO + #if CIRCUITPY && !(defined(__unix__) || defined(__APPLE__)) #include "shared-bindings/supervisor/__init__.h" #endif #include "supervisor/shared/translate/translate.h" -#if MICROPY_PY_UASYNCIO - // Used when task cannot be guaranteed to be non-NULL. #define TASK_PAIRHEAP(task) ((task) ? &(task)->pairheap : NULL) @@ -70,6 +70,7 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf); /******************************************************************************/ // Ticks for task ordering in pairing heap +// CIRCUITPY-style ticks #define _TICKS_PERIOD (1lu << 29) #define _TICKS_MAX (_TICKS_PERIOD - 1) #define _TICKS_HALFPERIOD (_TICKS_PERIOD >> 1) @@ -105,8 +106,7 @@ STATIC int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) { STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)args; mp_arg_check_num(n_args, n_kw, 0, 0, false); - mp_obj_task_queue_t *self = m_new_obj(mp_obj_task_queue_t); - self->base.type = type; + mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type); self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt); return MP_OBJ_FROM_PTR(self); } @@ -121,7 +121,7 @@ STATIC mp_obj_t task_queue_peek(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek); -STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) { +STATIC mp_obj_t task_queue_push(size_t n_args, const mp_obj_t *args) { mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]); mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]); task->data = mp_const_none; @@ -134,9 +134,9 @@ STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) { self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task)); return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_sorted_obj, 2, 3, task_queue_push_sorted); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_obj, 2, 3, task_queue_push); -STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) { +STATIC mp_obj_t task_queue_pop(mp_obj_t self_in) { mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap); if (head == NULL) { @@ -145,7 +145,7 @@ STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) { self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap); return MP_OBJ_FROM_PTR(head); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_head_obj, task_queue_pop_head); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_obj, task_queue_pop); STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) { mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in); @@ -157,10 +157,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(task_queue_remove_obj, task_queue_remove); STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) }, - { MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_sorted_obj) }, - { MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_sorted_obj) }, - { MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_head_obj) }, + { MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) }, + { MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) }, { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) }, + + // CIRCUITPYTHON: remove these after the bundle need not support 8.x + { MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_obj) }, + { MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_obj) }, + { MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_obj) }, }; STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table); @@ -223,18 +227,18 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) { // Not on the main running queue, remove the task from the queue it's on. dest[2] = MP_OBJ_FROM_PTR(self); mp_call_method_n_kw(1, 0, dest); - // _task_queue.push_head(self) + // _task_queue.push(self) dest[0] = _task_queue; dest[1] = MP_OBJ_FROM_PTR(self); - task_queue_push_sorted(2, dest); + task_queue_push(2, dest); } else if (ticks_diff(self->ph_key, ticks()) > 0) { // On the main running queue but scheduled in the future, so bring it forward to now. // _task_queue.remove(self) task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self)); - // _task_queue.push_head(self) + // _task_queue.push(self) dest[0] = _task_queue; dest[1] = MP_OBJ_FROM_PTR(self); - task_queue_push_sorted(2, dest); + task_queue_push(2, dest); } self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError)); @@ -243,6 +247,7 @@ STATIC mp_obj_t task_cancel(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel); +// CIRCUITPY provides __await__(). STATIC mp_obj_t task_await(mp_obj_t self_in) { return task_getiter(self_in, NULL); } @@ -266,6 +271,7 @@ STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { dest[1] = self_in; } else if (attr == MP_QSTR_ph_key) { dest[0] = self->ph_key; + // CIRCUITPY provides __await__(). } else if (attr == MP_QSTR___await__) { dest[0] = MP_OBJ_FROM_PTR(&task_await_obj); dest[1] = self_in; @@ -291,6 +297,9 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { } else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) { // Allocate the waiting queue. self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL); + } else if (mp_obj_get_type(self->state) != &task_queue_type) { + // Task has state used for another purpose, so can't also wait on it. + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't wait")); } return self_in; } @@ -298,6 +307,7 @@ STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) { STATIC mp_obj_t task_iternext(mp_obj_t self_in) { mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in); if (TASK_IS_DONE(self)) { + // CIRCUITPY if (self->data == mp_const_none) { // Task finished but has already been sent to the loop's exception handler. mp_raise_StopIteration(MP_OBJ_NULL); @@ -309,7 +319,7 @@ STATIC mp_obj_t task_iternext(mp_obj_t self_in) { // Put calling task on waiting queue. mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task)); mp_obj_t args[2] = { self->state, cur_task }; - task_queue_push_sorted(2, args); + task_queue_push(2, args); // Set calling task's data to this task that it waits on, to double-link it. ((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in; } @@ -347,6 +357,6 @@ const mp_obj_module_t mp_module_uasyncio = { .globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals, }; -MP_REGISTER_MODULE(MP_QSTR__asyncio, mp_module_uasyncio, MICROPY_PY_UASYNCIO); +MP_REGISTER_MODULE(MP_QSTR__uasyncio, mp_module_uasyncio); #endif // MICROPY_PY_UASYNCIO diff --git a/extmod/modubinascii.c b/extmod/modubinascii.c index 5aa9eacefdfe2..d95f6f555468b 100644 --- a/extmod/modubinascii.c +++ b/extmod/modubinascii.c @@ -1,8 +1,28 @@ -// Copyright (c) 2014 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: 2022 Beat Ludin for Adafruit Industries -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -13,6 +33,8 @@ #include "supervisor/shared/translate/translate.h" +#if MICROPY_PY_UBINASCII + static void check_not_unicode(const mp_obj_t arg) { #if MICROPY_CPYTHON_COMPAT if (mp_obj_is_str(arg)) { @@ -20,7 +42,6 @@ static void check_not_unicode(const mp_obj_t arg) { } #endif } - STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) { // First argument is the data to convert. // Second argument is an optional separator to be used between values. @@ -154,13 +175,21 @@ STATIC mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64); -STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) { - check_not_unicode(data); +STATIC mp_obj_t mod_binascii_b2a_base64(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_newline }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_newline, MP_ARG_BOOL, {.u_bool = true} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + uint8_t newline = args[ARG_newline].u_bool; + check_not_unicode(pos_args[0]); mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(pos_args[0], &bufinfo, MP_BUFFER_READ); vstr_t vstr; - vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + 1); + vstr_init_len(&vstr, ((bufinfo.len != 0) ? (((bufinfo.len - 1) / 3) + 1) * 4 : 0) + newline); // First pass, we convert input buffer to numeric base 64 values byte *in = bufinfo.buf, *out = (byte *)vstr.buf; @@ -186,7 +215,7 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) { // Second pass, we convert number base 64 values to actual base64 ascii encoding out = (byte *)vstr.buf; - for (mp_uint_t j = vstr.len - 1; j--;) { + for (mp_uint_t j = vstr.len - newline; j--;) { if (*out < 26) { *out += 'A'; } else if (*out < 52) { @@ -202,10 +231,15 @@ STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) { } out++; } - *out = '\n'; + if (newline) { + *out = '\n'; + } return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_binascii_b2a_base64_obj, 1, mod_binascii_b2a_base64); + +// CIRCUITPY uses a self-contained implementation of CRC32, +// instead of depending on uzlib, like MicroPython. /* * CRC32 checksum @@ -296,4 +330,6 @@ const mp_obj_module_t mp_module_ubinascii = { .globals = (mp_obj_dict_t *)&mp_module_binascii_globals, }; -MP_REGISTER_MODULE(MP_QSTR_binascii, mp_module_ubinascii, MICROPY_PY_UBINASCII); +MP_REGISTER_MODULE(MP_QSTR_ubinascii, mp_module_ubinascii); + +#endif // MICROPY_PY_UBINASCII diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 38f700c05521f..78cf44a17ae60 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -1,7 +1,28 @@ -// Copyright (c) 2014-2018 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2018 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -76,8 +97,7 @@ STATIC NORETURN void syntax_error(void) { STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, 3, false); - mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); - o->base.type = type; + mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, type); o->addr = (void *)(uintptr_t)mp_obj_int_get_truncated(args[0]); o->desc = args[1]; o->flags = LAYOUT_NATIVE; @@ -444,8 +464,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set switch (agg_type) { case STRUCT: { - mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); - o->base.type = &uctypes_struct_type; + mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type); o->desc = sub->items[1]; o->addr = self->addr + offset; o->flags = self->flags; @@ -460,8 +479,7 @@ STATIC mp_obj_t uctypes_struct_attr_op(mp_obj_t self_in, qstr attr, mp_obj_t set MP_FALLTHROUGH } case PTR: { - mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); - o->base.type = &uctypes_struct_type; + mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type); o->desc = MP_OBJ_FROM_PTR(sub); o->addr = self->addr + offset; o->flags = self->flags; @@ -533,8 +551,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob } else if (value == MP_OBJ_SENTINEL) { mp_uint_t dummy = 0; mp_uint_t size = uctypes_struct_size(t->items[2], self->flags, &dummy); - mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); - o->base.type = &uctypes_struct_type; + mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type); o->desc = t->items[2]; o->addr = self->addr + size * index; o->flags = self->flags; @@ -551,8 +568,7 @@ STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_ob } else { mp_uint_t dummy = 0; mp_uint_t size = uctypes_struct_size(t->items[1], self->flags, &dummy); - mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t); - o->base.type = &uctypes_struct_type; + mp_obj_uctypes_struct_t *o = mp_obj_malloc(mp_obj_uctypes_struct_t, &uctypes_struct_type); o->desc = t->items[1]; o->addr = p + size * index; o->flags = self->flags; @@ -706,4 +722,6 @@ const mp_obj_module_t mp_module_uctypes = { .globals = (mp_obj_dict_t *)&mp_module_uctypes_globals, }; +MP_REGISTER_MODULE(MP_QSTR_uctypes, mp_module_uctypes); + #endif diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c index a84254c56620b..11f8d1e03d433 100644 --- a/extmod/moduhashlib.c +++ b/extmod/moduhashlib.c @@ -1,7 +1,28 @@ -// Copyright (c) 2014 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -39,7 +60,6 @@ #endif - typedef struct _mp_obj_hash_t { mp_obj_base_t base; bool final; // if set, update and digest raise an exception @@ -65,8 +85,7 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg); STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context)); - o->base.type = type; + mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context), type); o->final = false; mbedtls_sha256_init((mbedtls_sha256_context *)&o->state); mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0); @@ -105,13 +124,11 @@ static void check_not_unicode(const mp_obj_t arg) { #endif } -#if MICROPY_PY_UHASHLIB_SHA256 #include "lib/crypto-algorithms/sha256.c" STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX)); - o->base.type = type; + mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX), type); o->final = false; sha256_init((CRYAL_SHA256_CTX *)o->state); if (n_args == 1) { @@ -159,16 +176,13 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = { }; #endif -#endif - #if MICROPY_PY_UHASHLIB_SHA1 STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg); #if MICROPY_SSL_AXTLS -STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { - mp_arg_check_num(n_args, kw_args, 0, 1, false); - mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX)); - o->base.type = type; +STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 1, false); + mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(SHA1_CTX), type); o->final = false; SHA1_Init((SHA1_CTX *)o->state); if (n_args == 1) { @@ -178,7 +192,6 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, } STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) { - check_not_unicode(arg); mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in); uhashlib_ensure_not_final(self); mp_buffer_info_t bufinfo; @@ -208,8 +221,7 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) { STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context)); - o->base.type = type; + mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context), type); o->final = false; mbedtls_sha1_init((mbedtls_sha1_context *)o->state); mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state); @@ -263,8 +275,7 @@ STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg); #if MICROPY_SSL_AXTLS STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX)); - o->base.type = type; + mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(MD5_CTX), type); o->final = false; MD5_Init((MD5_CTX *)o->state); if (n_args == 1) { @@ -303,8 +314,7 @@ STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) { STATIC mp_obj_t uhashlib_md5_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context)); - o->base.type = type; + mp_obj_hash_t *o = mp_obj_malloc_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context), type); o->final = false; mbedtls_md5_init((mbedtls_md5_context *)o->state); mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state); @@ -372,4 +382,6 @@ const mp_obj_module_t mp_module_uhashlib = { .globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals, }; +MP_REGISTER_MODULE(MP_QSTR_uhashlib, mp_module_uhashlib); + #endif // MICROPY_PY_UHASHLIB diff --git a/extmod/moduheapq.c b/extmod/moduheapq.c index 0200245f86d29..f48d9bceb1cbf 100644 --- a/extmod/moduheapq.c +++ b/extmod/moduheapq.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/objlist.h" #include "py/runtime.h" @@ -98,6 +119,8 @@ const mp_obj_module_t mp_module_uheapq = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&mp_module_uheapq_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_uheapq, mp_module_uheapq); #endif #endif // MICROPY_PY_UHEAPQ diff --git a/extmod/modujson.c b/extmod/modujson.c index cff02ae95ccd5..14e45e2cc12be 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2019 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include @@ -112,6 +133,7 @@ typedef struct _ujson_stream_t { mp_obj_t stream_obj; mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode); int errcode; + // CIRCUITPY mp_obj_t python_readinto[2 + 1]; mp_obj_array_t bytearray_obj; size_t start; @@ -136,6 +158,8 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) { return s->cur; } +// CIRCUITPY + // We read from an object's `readinto` method in chunks larger than the json // parser needs to reduce the number of function calls done. @@ -375,6 +399,8 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) { } } success: + // CIRCUITPY + // It is legal for a stream to have contents after JSON. // E.g., A UART is not closed after receiving an object; in load() we will // return the first complete JSON object, while in loads() we will retain @@ -432,6 +458,6 @@ const mp_obj_module_t mp_module_ujson = { .globals = (mp_obj_dict_t *)&mp_module_ujson_globals, }; -MP_REGISTER_MODULE(MP_QSTR_json, mp_module_ujson, MICROPY_PY_UJSON); +MP_REGISTER_MODULE(MP_QSTR_ujson, mp_module_ujson); #endif // MICROPY_PY_UJSON diff --git a/extmod/moduos.c b/extmod/moduos.c new file mode 100644 index 0000000000000..a1752deb4aa6f --- /dev/null +++ b/extmod/moduos.c @@ -0,0 +1,186 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016-2022 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objstr.h" +#include "py/runtime.h" + +#if MICROPY_PY_UOS + +#include "extmod/misc.h" +#include "extmod/vfs.h" + +#if MICROPY_VFS_FAT +#include "extmod/vfs_fat.h" +#endif + +#if MICROPY_VFS_LFS1 || MICROPY_VFS_LFS2 +#include "extmod/vfs_lfs.h" +#endif + +#if MICROPY_VFS_POSIX +#include "extmod/vfs_posix.h" +#endif + +#if MICROPY_PY_UOS_UNAME +#include "genhdr/mpversion.h" +#endif + +#ifdef MICROPY_PY_UOS_INCLUDEFILE +#include MICROPY_PY_UOS_INCLUDEFILE +#endif + +#ifdef MICROPY_BUILD_TYPE +#define MICROPY_BUILD_TYPE_PAREN " (" MICROPY_BUILD_TYPE ")" +#else +#define MICROPY_BUILD_TYPE_PAREN +#endif + +#if MICROPY_PY_UOS_UNAME + +#if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC +#define CONST_RELEASE +#else +#define CONST_RELEASE const +#endif + +STATIC const qstr mp_uos_uname_info_fields[] = { + MP_QSTR_sysname, + MP_QSTR_nodename, + MP_QSTR_release, + MP_QSTR_version, + MP_QSTR_machine +}; +STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM); +STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM); +STATIC CONST_RELEASE MP_DEFINE_STR_OBJ(mp_uos_uname_info_release_obj, MICROPY_VERSION_STRING); +STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE MICROPY_BUILD_TYPE_PAREN); +STATIC const MP_DEFINE_STR_OBJ(mp_uos_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + +STATIC MP_DEFINE_ATTRTUPLE( + mp_uos_uname_info_obj, + mp_uos_uname_info_fields, + 5, + MP_ROM_PTR(&mp_uos_uname_info_sysname_obj), + MP_ROM_PTR(&mp_uos_uname_info_nodename_obj), + MP_ROM_PTR(&mp_uos_uname_info_release_obj), + MP_ROM_PTR(&mp_uos_uname_info_version_obj), + MP_ROM_PTR(&mp_uos_uname_info_machine_obj) + ); + +STATIC mp_obj_t mp_uos_uname(void) { + #if MICROPY_PY_UOS_UNAME_RELEASE_DYNAMIC + const char *release = mp_uos_uname_release(); + mp_uos_uname_info_release_obj.len = strlen(release); + mp_uos_uname_info_release_obj.data = (const byte *)release; + #endif + return MP_OBJ_FROM_PTR(&mp_uos_uname_info_obj); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(mp_uos_uname_obj, mp_uos_uname); + +#endif + +STATIC const mp_rom_map_elem_t os_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, + + #if MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV + { MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mp_uos_getenv_obj) }, + #if defined(MICROPY_UNIX_COVERAGE) + { MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mp_uos_getenv_int_obj) }, + { MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mp_uos_getenv_str_obj) }, + #endif + + { MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_uos_putenv_obj) }, + { MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_uos_unsetenv_obj) }, + #endif + #if MICROPY_PY_UOS_SEP + { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) }, + #endif + #if MICROPY_PY_UOS_SYNC + { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_uos_sync_obj) }, + #endif + #if MICROPY_PY_UOS_SYSTEM + { MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mp_uos_system_obj) }, + #endif + #if MICROPY_PY_UOS_UNAME + { MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&mp_uos_uname_obj) }, + #endif + #if MICROPY_PY_UOS_URANDOM + { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_uos_urandom_obj) }, + #endif + + #if MICROPY_VFS + { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) }, + { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) }, + { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) }, + { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) }, + { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove + #endif + + // The following are MicroPython extensions. + + #if MICROPY_PY_OS_DUPTERM + { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) }, + #endif + #if MICROPY_PY_UOS_DUPTERM_NOTIFY + { MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&mp_uos_dupterm_notify_obj) }, + #endif + #if MICROPY_PY_UOS_ERRNO + { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_uos_errno_obj) }, + #endif + + #if MICROPY_VFS + { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) }, + { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) }, + #if MICROPY_VFS_FAT + { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, + #endif + #if MICROPY_VFS_LFS1 + { MP_ROM_QSTR(MP_QSTR_VfsLfs1), MP_ROM_PTR(&mp_type_vfs_lfs1) }, + #endif + #if MICROPY_VFS_LFS2 + { MP_ROM_QSTR(MP_QSTR_VfsLfs2), MP_ROM_PTR(&mp_type_vfs_lfs2) }, + #endif + #if MICROPY_VFS_POSIX + { MP_ROM_QSTR(MP_QSTR_VfsPosix), MP_ROM_PTR(&mp_type_vfs_posix) }, + #endif + #endif +}; +STATIC MP_DEFINE_CONST_DICT(os_module_globals, os_module_globals_table); + +const mp_obj_module_t mp_module_uos = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&os_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_uos, mp_module_uos); + +#endif // MICROPY_PY_UOS diff --git a/extmod/moduplatform.c b/extmod/moduplatform.c index 820feb312aaf3..1b35b08aa7214 100644 --- a/extmod/moduplatform.c +++ b/extmod/moduplatform.c @@ -29,87 +29,19 @@ #include "py/objtuple.h" #include "py/objstr.h" #include "py/mphal.h" +#include "extmod/moduplatform.h" #include "genhdr/mpversion.h" #if MICROPY_PY_UPLATFORM // platform - Access to underlying platform's identifying data -// TODO: Add more architectures, compilers and libraries. -// See: https://sourceforge.net/p/predef/wiki/Home/ - -#if defined(__ARM_ARCH) -#define PLATFORM_ARCH "arm" -#elif defined(__x86_64__) || defined(_WIN64) -#define PLATFORM_ARCH "x86_64" -#elif defined(__i386__) || defined(_M_IX86) -#define PLATFORM_ARCH "x86" -#elif defined(__xtensa__) || defined(_M_IX86) -#define PLATFORM_ARCH "xtensa" -#else -#define PLATFORM_ARCH "" -#endif - -#if defined(__GNUC__) -#define PLATFORM_COMPILER \ - "GCC " \ - MP_STRINGIFY(__GNUC__) "." \ - MP_STRINGIFY(__GNUC_MINOR__) "." \ - MP_STRINGIFY(__GNUC_PATCHLEVEL__) -#elif defined(__ARMCC_VERSION) -#define PLATFORM_COMPILER \ - "ARMCC " \ - MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \ - MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \ - MP_STRINGIFY((__ARMCC_VERSION % 10000)) -#elif defined(_MSC_VER) -#if defined(_WIN64) -#define COMPILER_BITS "64 bit" -#elif defined(_M_IX86) -#define COMPILER_BITS "32 bit" -#else -#define COMPILER_BITS "" -#endif -#define PLATFORM_COMPILER \ - "MSC v." MP_STRINGIFY(_MSC_VER) " " COMPILER_BITS -#else -#define PLATFORM_COMPILER "" -#endif - -#if defined(__GLIBC__) -#define PLATFORM_LIBC_LIB "glibc" -#define PLATFORM_LIBC_VER \ - MP_STRINGIFY(__GLIBC__) "." \ - MP_STRINGIFY(__GLIBC_MINOR__) -#elif defined(__NEWLIB__) -#define PLATFORM_LIBC_LIB "newlib" -#define PLATFORM_LIBC_VER _NEWLIB_VERSION -#else -#define PLATFORM_LIBC_LIB "" -#define PLATFORM_LIBC_VER "" -#endif - -#if defined(__linux) -#define PLATFORM_SYSTEM "Linux" -#elif defined(__unix__) -#define PLATFORM_SYSTEM "Unix" -#elif defined(__CYGWIN__) -#define PLATFORM_SYSTEM "Cygwin" -#elif defined(_WIN32) -#define PLATFORM_SYSTEM "Windows" -#else -#define PLATFORM_SYSTEM "MicroPython" -#endif - -#ifndef MICROPY_PLATFORM_VERSION -#define MICROPY_PLATFORM_VERSION "" -#endif - -STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, PLATFORM_SYSTEM "-" MICROPY_VERSION_STRING "-" \ - PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" PLATFORM_LIBC_LIB "" PLATFORM_LIBC_VER); -STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, PLATFORM_COMPILER); -STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, PLATFORM_LIBC_LIB); -STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, PLATFORM_LIBC_VER); +STATIC const MP_DEFINE_STR_OBJ(info_platform_obj, MICROPY_PLATFORM_SYSTEM "-" \ + MICROPY_VERSION_STRING "-" MICROPY_PLATFORM_ARCH "-" MICROPY_PLATFORM_VERSION "-with-" \ + MICROPY_PLATFORM_LIBC_LIB "" MICROPY_PLATFORM_LIBC_VER); +STATIC const MP_DEFINE_STR_OBJ(info_python_compiler_obj, MICROPY_PLATFORM_COMPILER); +STATIC const MP_DEFINE_STR_OBJ(info_libc_lib_obj, MICROPY_PLATFORM_LIBC_LIB); +STATIC const MP_DEFINE_STR_OBJ(info_libc_ver_obj, MICROPY_PLATFORM_LIBC_VER); STATIC const mp_rom_obj_tuple_t info_libc_tuple_obj = { {&mp_type_tuple}, 2, {MP_ROM_PTR(&info_libc_lib_obj), MP_ROM_PTR(&info_libc_ver_obj)} }; @@ -143,4 +75,6 @@ const mp_obj_module_t mp_module_uplatform = { .globals = (mp_obj_dict_t *)&modplatform_globals, }; +MP_REGISTER_MODULE(MP_QSTR_uplatform, mp_module_uplatform); + #endif // MICROPY_PY_UPLATFORM diff --git a/extmod/moduplatform.h b/extmod/moduplatform.h new file mode 100644 index 0000000000000..d52ad7da7d9df --- /dev/null +++ b/extmod/moduplatform.h @@ -0,0 +1,105 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2021 Ibrahim Abdelkader + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_MODUPLATFORM_H +#define MICROPY_INCLUDED_MODUPLATFORM_H + +#include "py/misc.h" // For MP_STRINGIFY. +#include "py/mpconfig.h" + +// Preprocessor directives identifying the platform. +// The (u)platform module itself is guarded by MICROPY_PY_UPLATFORM, see the +// .c file, but these are made available because they're generally usable. +// TODO: Add more architectures, compilers and libraries. +// See: https://sourceforge.net/p/predef/wiki/Home/ + +#if defined(__ARM_ARCH) +#define MICROPY_PLATFORM_ARCH "arm" +#elif defined(__x86_64__) || defined(_WIN64) +#define MICROPY_PLATFORM_ARCH "x86_64" +#elif defined(__i386__) || defined(_M_IX86) +#define MICROPY_PLATFORM_ARCH "x86" +#elif defined(__xtensa__) || defined(_M_IX86) +#define MICROPY_PLATFORM_ARCH "xtensa" +#else +#define MICROPY_PLATFORM_ARCH "" +#endif + +#if defined(__GNUC__) +#define MICROPY_PLATFORM_COMPILER \ + "GCC " \ + MP_STRINGIFY(__GNUC__) "." \ + MP_STRINGIFY(__GNUC_MINOR__) "." \ + MP_STRINGIFY(__GNUC_PATCHLEVEL__) +#elif defined(__ARMCC_VERSION) +#define MICROPY_PLATFORM_COMPILER \ + "ARMCC " \ + MP_STRINGIFY((__ARMCC_VERSION / 1000000)) "." \ + MP_STRINGIFY((__ARMCC_VERSION / 10000 % 100)) "." \ + MP_STRINGIFY((__ARMCC_VERSION % 10000)) +#elif defined(_MSC_VER) +#if defined(_WIN64) +#define MICROPY_PLATFORM_COMPILER_BITS "64 bit" +#elif defined(_M_IX86) +#define MICROPY_PLATFORM_COMPILER_BITS "32 bit" +#else +#define MICROPY_PLATFORM_COMPILER_BITS "" +#endif +#define MICROPY_PLATFORM_COMPILER \ + "MSC v." MP_STRINGIFY(_MSC_VER) " " MICROPY_PLATFORM_COMPILER_BITS +#else +#define MICROPY_PLATFORM_COMPILER "" +#endif + +#if defined(__GLIBC__) +#define MICROPY_PLATFORM_LIBC_LIB "glibc" +#define MICROPY_PLATFORM_LIBC_VER \ + MP_STRINGIFY(__GLIBC__) "." \ + MP_STRINGIFY(__GLIBC_MINOR__) +#elif defined(__NEWLIB__) +#define MICROPY_PLATFORM_LIBC_LIB "newlib" +#define MICROPY_PLATFORM_LIBC_VER _NEWLIB_VERSION +#else +#define MICROPY_PLATFORM_LIBC_LIB "" +#define MICROPY_PLATFORM_LIBC_VER "" +#endif + +#if defined(__linux) +#define MICROPY_PLATFORM_SYSTEM "Linux" +#elif defined(__unix__) +#define MICROPY_PLATFORM_SYSTEM "Unix" +#elif defined(__CYGWIN__) +#define MICROPY_PLATFORM_SYSTEM "Cygwin" +#elif defined(_WIN32) +#define MICROPY_PLATFORM_SYSTEM "Windows" +#else +#define MICROPY_PLATFORM_SYSTEM "MicroPython" +#endif + +#ifndef MICROPY_PLATFORM_VERSION +#define MICROPY_PLATFORM_VERSION "" +#endif + +#endif // MICROPY_INCLUDED_MODUPLATFORM_H diff --git a/extmod/modurandom.c b/extmod/modurandom.c index e304d0b72803b..b66162719034b 100644 --- a/extmod/modurandom.c +++ b/extmod/modurandom.c @@ -1,7 +1,28 @@ -// Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -195,7 +216,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform); #endif // MICROPY_PY_URANDOM_EXTRA_FUNCS #if SEED_ON_IMPORT -STATIC mp_obj_t mod_urandom___init__() { +STATIC mp_obj_t mod_urandom___init__(void) { // This module may be imported by more than one name so need to ensure // that it's only ever seeded once. static bool seeded = false; @@ -233,6 +254,8 @@ const mp_obj_module_t mp_module_urandom = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&mp_module_urandom_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_urandom, mp_module_urandom); #endif #endif // MICROPY_PY_URANDOM diff --git a/extmod/modure.c b/extmod/modure.c index c65eddb988524..805c23d4adb37 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -1,7 +1,28 @@ -// Copyright (c) 2014 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -18,6 +39,7 @@ #include "lib/re1.5/re1.5.h" +// CIRCUITPY #if MICROPY_PY_URE_DEBUG #define FLAG_DEBUG 0x1000 #endif @@ -168,7 +190,7 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { } Subject subj; size_t len; - subj.begin = mp_obj_str_get_data(args[1], &len); + subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; #if MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME) @@ -231,7 +253,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) { Subject subj; size_t len; const mp_obj_type_t *str_type = mp_obj_get_type(args[1]); - subj.begin = mp_obj_str_get_data(args[1], &len); + subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; int caps_num = (self->re.sub + 1) * 2; @@ -291,7 +313,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { size_t where_len; const char *where_str = mp_obj_str_get_data(where, &where_len); Subject subj; - subj.begin = where_str; + subj.begin_line = subj.begin = where_str; subj.end = subj.begin + where_len; int caps_num = (self->re.sub + 1) * 2; @@ -421,8 +443,7 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { if (size == -1) { goto error; } - mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size); - o->base.type = &re_type; + mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, char, size, &re_type); #if MICROPY_PY_URE_DEBUG int flags = 0; if (n_args > 1) { @@ -470,7 +491,7 @@ const mp_obj_module_t mp_module_ure = { .globals = (mp_obj_dict_t *)&mp_module_re_globals, }; -MP_REGISTER_MODULE(MP_QSTR_re, mp_module_ure, MICROPY_PY_URE); +MP_REGISTER_MODULE(MP_QSTR_ure, mp_module_ure); #endif // Source files #include'd here to make sure they're compiled in diff --git a/extmod/moduselect.c b/extmod/moduselect.c index d388438313640..e41adbc791689 100644 --- a/extmod/moduselect.c +++ b/extmod/moduselect.c @@ -1,8 +1,29 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George -// SPDX-FileCopyrightText: Copyright (c) 2015-2017 Paul Sokolovsky -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * Copyright (c) 2015-2017 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/mpconfig.h" #if MICROPY_PY_USELECT @@ -151,6 +172,7 @@ STATIC mp_obj_t select_select(size_t n_args, const mp_obj_t *args) { mp_map_deinit(&poll_map); return mp_obj_new_tuple(3, list_array); } + // CIRCUITPY RUN_BACKGROUND_TASKS; } } @@ -230,6 +252,7 @@ STATIC mp_uint_t poll_poll_internal(uint n_args, const mp_obj_t *args) { if (n_ready > 0 || (timeout != (mp_uint_t)-1 && mp_hal_ticks_ms() - start_tick >= timeout)) { break; } + // CIRCUITPY RUN_BACKGROUND_TASKS; if (mp_hal_is_interrupted()) { return 0; @@ -333,8 +356,7 @@ STATIC const mp_obj_type_t mp_type_poll = { // poll() STATIC mp_obj_t select_poll(void) { - mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t); - poll->base.type = &mp_type_poll; + mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll); mp_map_init(&poll->poll_map, 0); poll->iter_cnt = 0; poll->ret_tuple = MP_OBJ_NULL; @@ -361,6 +383,6 @@ const mp_obj_module_t mp_module_uselect = { .globals = (mp_obj_dict_t *)&mp_module_select_globals, }; -MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect, MICROPY_PY_USELECT); +MP_REGISTER_MODULE(MP_QSTR_select, mp_module_uselect); #endif // MICROPY_PY_USELECT diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c index fcef14ce982d6..7cabfee4be409 100644 --- a/extmod/modutimeq.c +++ b/extmod/modutimeq.c @@ -1,8 +1,29 @@ -// Copyright (c) 2016-2017 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * Copyright (c) 2016-2017 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include @@ -58,8 +79,7 @@ STATIC bool time_less_than(struct qentry *item, struct qentry *parent) { STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); mp_uint_t alloc = mp_obj_get_int(args[0]); - mp_obj_utimeq_t *o = m_new_obj_var(mp_obj_utimeq_t, struct qentry, alloc); - o->base.type = type; + mp_obj_utimeq_t *o = mp_obj_malloc_var(mp_obj_utimeq_t, struct qentry, alloc, type); memset(o->items, 0, sizeof(*o->items) * alloc); o->alloc = alloc; o->len = 0; @@ -214,4 +234,6 @@ const mp_obj_module_t mp_module_utimeq = { .globals = (mp_obj_dict_t *)&mp_module_utimeq_globals, }; +MP_REGISTER_MODULE(MP_QSTR_utimeq, mp_module_utimeq); + #endif // MICROPY_PY_UTIMEQ diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c index 6a1a2d611144b..5c16ea732cb05 100644 --- a/extmod/moduzlib.c +++ b/extmod/moduzlib.c @@ -1,7 +1,28 @@ -// Copyright (c) 2014-2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -51,15 +72,14 @@ STATIC int read_src_stream(TINF_DATA *data) { STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 2, false); mp_get_stream_raise(args[0], MP_STREAM_OP_READ); - mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t); - o->base.type = type; + mp_obj_decompio_t *o = mp_obj_malloc(mp_obj_decompio_t, type); memset(&o->decomp, 0, sizeof(o->decomp)); o->decomp.readSource = read_src_stream; o->src_stream = args[0]; o->eof = false; mp_int_t dict_opt = 0; - int dict_sz; + uint dict_sz; if (n_args > 1) { dict_opt = mp_obj_get_int(args[1]); } @@ -76,7 +96,10 @@ STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size header_error: mp_raise_ValueError(MP_ERROR_TEXT("compression header")); } - dict_sz = 1 << dict_opt; + // RFC 1950 section 2.2: + // CINFO is the base-2 logarithm of the LZ77 window size, + // minus eight (CINFO=7 indicates a 32K window size) + dict_sz = 1 << (dict_opt + 8); } else { dict_sz = 1 << -dict_opt; } @@ -92,12 +115,13 @@ STATIC mp_uint_t decompio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er } o->decomp.dest = buf; - o->decomp.dest_limit = (unsigned char *)buf + size; + o->decomp.dest_limit = (byte *)buf + size; int st = uzlib_uncompress_chksum(&o->decomp); if (st == TINF_DONE) { o->eof = true; } if (st < 0) { + DEBUG_printf("uncompress error=" INT_FMT "\n", st); *errcode = MP_EINVAL; return MP_STREAM_ERROR; } @@ -146,9 +170,10 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) { decomp->dest = dest_buf; decomp->dest_limit = dest_buf + dest_buf_size; - DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", decomp->destSize); + DEBUG_printf("uzlib: Initial out buffer: " UINT_FMT " bytes\n", dest_buf_size); decomp->source = bufinfo.buf; - decomp->source_limit = (unsigned char *)bufinfo.buf + bufinfo.len; + decomp->source_limit = (byte *)bufinfo.buf + bufinfo.len; + int st; bool is_zlib = true; @@ -175,7 +200,7 @@ STATIC mp_obj_t mod_uzlib_decompress(size_t n_args, const mp_obj_t *args) { dest_buf = m_renew(byte, dest_buf, dest_buf_size, dest_buf_size + 256); dest_buf_size += 256; decomp->dest = dest_buf + offset; - decomp->dest_limit = dest_buf + offset + 256; + decomp->dest_limit = decomp->dest + 256; } mp_uint_t final_sz = decomp->dest - dest_buf; @@ -203,6 +228,9 @@ const mp_obj_module_t mp_module_uzlib = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&mp_module_uzlib_globals, }; + + +MP_REGISTER_MODULE(MP_QSTR_uzlib, mp_module_uzlib); #endif // Source files #include'd here to make sure they're compiled in diff --git a/extmod/uasyncio/__init__.py b/extmod/uasyncio/__init__.py deleted file mode 100644 index fa64438f6b2a0..0000000000000 --- a/extmod/uasyncio/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# MicroPython uasyncio module -# MIT license; Copyright (c) 2019 Damien P. George - -from .core import * - -__version__ = (3, 0, 0) - -_attrs = { - "wait_for": "funcs", - "wait_for_ms": "funcs", - "gather": "funcs", - "Event": "event", - "ThreadSafeFlag": "event", - "Lock": "lock", - "open_connection": "stream", - "start_server": "stream", - "StreamReader": "stream", - "StreamWriter": "stream", -} - -# Lazy loader, effectively does: -# global attr -# from .mod import attr -def __getattr__(attr): - mod = _attrs.get(attr, None) - if mod is None: - raise AttributeError(attr) - value = getattr(__import__(mod, None, None, True, 1), attr) - globals()[attr] = value - return value diff --git a/extmod/uasyncio/core.py b/extmod/uasyncio/core.py deleted file mode 100644 index c3ce3ccafae09..0000000000000 --- a/extmod/uasyncio/core.py +++ /dev/null @@ -1,295 +0,0 @@ -# MicroPython uasyncio module -# MIT license; Copyright (c) 2019 Damien P. George - -from time import ticks_ms as ticks, ticks_diff, ticks_add -import sys, select - -# Import TaskQueue and Task, preferring built-in C code over Python code -try: - from _uasyncio import TaskQueue, Task -except: - from .task import TaskQueue, Task - - -################################################################################ -# Exceptions - - -class CancelledError(BaseException): - pass - - -class TimeoutError(Exception): - pass - - -# Used when calling Loop.call_exception_handler -_exc_context = {"message": "Task exception wasn't retrieved", "exception": None, "future": None} - - -################################################################################ -# Sleep functions - -# "Yield" once, then raise StopIteration -class SingletonGenerator: - def __init__(self): - self.state = None - self.exc = StopIteration() - - def __await__(self): - return self - - def __next__(self): - if self.state is not None: - _task_queue.push_sorted(cur_task, self.state) - self.state = None - return None - else: - self.exc.__traceback__ = None - raise self.exc - - -# Pause task execution for the given time (integer in milliseconds, uPy extension) -# Use a SingletonGenerator to do it without allocating on the heap -def sleep_ms(t, sgen=SingletonGenerator()): - assert sgen.state is None - sgen.state = ticks_add(ticks(), max(0, t)) - return sgen - - -# Pause task execution for the given time (in seconds) -def sleep(t): - return sleep_ms(int(t * 1000)) - - -################################################################################ -# Queue and poller for stream IO - - -class IOQueue: - def __init__(self): - self.poller = select.poll() - self.map = {} # maps id(stream) to [task_waiting_read, task_waiting_write, stream] - - def _enqueue(self, s, idx): - if id(s) not in self.map: - entry = [None, None, s] - entry[idx] = cur_task - self.map[id(s)] = entry - self.poller.register(s, select.POLLIN if idx == 0 else select.POLLOUT) - else: - sm = self.map[id(s)] - assert sm[idx] is None - assert sm[1 - idx] is not None - sm[idx] = cur_task - self.poller.modify(s, select.POLLIN | select.POLLOUT) - # Link task to this IOQueue so it can be removed if needed - cur_task.data = self - - def _dequeue(self, s): - del self.map[id(s)] - self.poller.unregister(s) - - def queue_read(self, s): - self._enqueue(s, 0) - - def queue_write(self, s): - self._enqueue(s, 1) - - def remove(self, task): - while True: - del_s = None - for k in self.map: # Iterate without allocating on the heap - q0, q1, s = self.map[k] - if q0 is task or q1 is task: - del_s = s - break - if del_s is not None: - self._dequeue(s) - else: - break - - def wait_io_event(self, dt): - for s, ev in self.poller.ipoll(dt): - sm = self.map[id(s)] - # print('poll', s, sm, ev) - if ev & ~select.POLLOUT and sm[0] is not None: - # POLLIN or error - _task_queue.push_head(sm[0]) - sm[0] = None - if ev & ~select.POLLIN and sm[1] is not None: - # POLLOUT or error - _task_queue.push_head(sm[1]) - sm[1] = None - if sm[0] is None and sm[1] is None: - self._dequeue(s) - elif sm[0] is None: - self.poller.modify(s, select.POLLOUT) - else: - self.poller.modify(s, select.POLLIN) - - -################################################################################ -# Main run loop - -# Ensure the awaitable is a task -def _promote_to_task(aw): - return aw if isinstance(aw, Task) else create_task(aw) - - -# Create and schedule a new task from a coroutine -def create_task(coro): - if not hasattr(coro, "send"): - raise TypeError("coroutine expected") - t = Task(coro, globals()) - _task_queue.push_head(t) - return t - - -# Keep scheduling tasks until there are none left to schedule -def run_until_complete(main_task=None): - global cur_task - excs_all = (CancelledError, Exception) # To prevent heap allocation in loop - excs_stop = (CancelledError, StopIteration) # To prevent heap allocation in loop - while True: - # Wait until the head of _task_queue is ready to run - dt = 1 - while dt > 0: - dt = -1 - t = _task_queue.peek() - if t: - # A task waiting on _task_queue; "ph_key" is time to schedule task at - dt = max(0, ticks_diff(t.ph_key, ticks())) - elif not _io_queue.map: - # No tasks can be woken so finished running - return - # print('(poll {})'.format(dt), len(_io_queue.map)) - _io_queue.wait_io_event(dt) - - # Get next task to run and continue it - t = _task_queue.pop_head() - cur_task = t - try: - # Continue running the coroutine, it's responsible for rescheduling itself - exc = t.data - if not exc: - t.coro.send(None) - else: - # If the task is finished and on the run queue and gets here, then it - # had an exception and was not await'ed on. Throwing into it now will - # raise StopIteration and the code below will catch this and run the - # call_exception_handler function. - t.data = None - t.coro.throw(exc) - except excs_all as er: - # Check the task is not on any event queue - assert t.data is None - # This task is done, check if it's the main task and then loop should stop - if t is main_task: - if isinstance(er, StopIteration): - return er.value - raise er - if t.state: - # Task was running but is now finished. - waiting = False - if t.state is True: - # "None" indicates that the task is complete and not await'ed on (yet). - t.state = None - else: - # Schedule any other tasks waiting on the completion of this task. - while t.state.peek(): - _task_queue.push_head(t.state.pop_head()) - waiting = True - # "False" indicates that the task is complete and has been await'ed on. - t.state = False - if not waiting and not isinstance(er, excs_stop): - # An exception ended this detached task, so queue it for later - # execution to handle the uncaught exception if no other task retrieves - # the exception in the meantime (this is handled by Task.throw). - _task_queue.push_head(t) - # Save return value of coro to pass up to caller. - t.data = er - elif t.state is None: - # Task is already finished and nothing await'ed on the task, - # so call the exception handler. - _exc_context["exception"] = exc - _exc_context["future"] = t - Loop.call_exception_handler(_exc_context) - - -# Create a new task from a coroutine and run it until it finishes -def run(coro): - return run_until_complete(create_task(coro)) - - -################################################################################ -# Event loop wrapper - - -async def _stopper(): - pass - - -_stop_task = None - - -class Loop: - _exc_handler = None - - def create_task(coro): - return create_task(coro) - - def run_forever(): - global _stop_task - _stop_task = Task(_stopper(), globals()) - run_until_complete(_stop_task) - # TODO should keep running until .stop() is called, even if there're no tasks left - - def run_until_complete(aw): - return run_until_complete(_promote_to_task(aw)) - - def stop(): - global _stop_task - if _stop_task is not None: - _task_queue.push_head(_stop_task) - # If stop() is called again, do nothing - _stop_task = None - - def close(): - pass - - def set_exception_handler(handler): - Loop._exc_handler = handler - - def get_exception_handler(): - return Loop._exc_handler - - def default_exception_handler(loop, context): - print(context["message"]) - print("future:", context["future"], "coro=", context["future"].coro) - sys.print_exception(context["exception"]) - - def call_exception_handler(context): - (Loop._exc_handler or Loop.default_exception_handler)(Loop, context) - - -# The runq_len and waitq_len arguments are for legacy uasyncio compatibility -def get_event_loop(runq_len=0, waitq_len=0): - return Loop - - -def current_task(): - return cur_task - - -def new_event_loop(): - global _task_queue, _io_queue - # TaskQueue of Task instances - _task_queue = TaskQueue() - # Task queue and poller for stream IO - _io_queue = IOQueue() - return Loop - - -# Initialise default event loop -new_event_loop() diff --git a/extmod/uasyncio/event.py b/extmod/uasyncio/event.py deleted file mode 100644 index a5b3bf9f47e65..0000000000000 --- a/extmod/uasyncio/event.py +++ /dev/null @@ -1,33 +0,0 @@ -# MicroPython uasyncio module -# MIT license; Copyright (c) 2019-2020 Damien P. George - -from . import core - -# Event class for primitive events that can be waited on, set, and cleared -class Event: - def __init__(self): - self.state = False # False=unset; True=set - self.waiting = core.TaskQueue() # Queue of Tasks waiting on completion of this event - - def is_set(self): - return self.state - - def set(self): - # Event becomes set, schedule any tasks waiting on it - # Note: This must not be called from anything except the thread running - # the asyncio loop (i.e. neither hard or soft IRQ, or a different thread). - while self.waiting.peek(): - core._task_queue.push_head(self.waiting.pop_head()) - self.state = True - - def clear(self): - self.state = False - - async def wait(self): - if not self.state: - # Event not set, put the calling task on the event's waiting queue - self.waiting.push_head(core.cur_task) - # Set calling task's data to the event's queue so it can be removed if needed - core.cur_task.data = self.waiting - yield - return True diff --git a/extmod/uasyncio/funcs.py b/extmod/uasyncio/funcs.py deleted file mode 100644 index 0ce48b015c1bd..0000000000000 --- a/extmod/uasyncio/funcs.py +++ /dev/null @@ -1,74 +0,0 @@ -# MicroPython uasyncio module -# MIT license; Copyright (c) 2019-2020 Damien P. George - -from . import core - - -async def wait_for(aw, timeout, sleep=core.sleep): - aw = core._promote_to_task(aw) - if timeout is None: - return await aw - - def runner(waiter, aw): - nonlocal status, result - try: - result = await aw - s = True - except BaseException as er: - s = er - if status is None: - # The waiter is still waiting, set status for it and cancel it. - status = s - waiter.cancel() - - # Run aw in a separate runner task that manages its exceptions. - status = None - result = None - runner_task = core.create_task(runner(core.cur_task, aw)) - - try: - # Wait for the timeout to elapse. - await sleep(timeout) - except core.CancelledError as er: - if status is True: - # aw completed successfully and cancelled the sleep, so return aw's result. - return result - elif status is None: - # This wait_for was cancelled externally, so cancel aw and re-raise. - status = True - runner_task.cancel() - raise er - else: - # aw raised an exception, propagate it out to the caller. - raise status - - # The sleep finished before aw, so cancel aw and raise TimeoutError. - status = True - runner_task.cancel() - await runner_task - raise core.TimeoutError - - -def wait_for_ms(aw, timeout): - return wait_for(aw, timeout, core.sleep_ms) - - -async def gather(*aws, return_exceptions=False): - ts = [core._promote_to_task(aw) for aw in aws] - for i in range(len(ts)): - try: - # TODO handle cancel of gather itself - # if ts[i].coro: - # iter(ts[i]).waiting.push_head(cur_task) - # try: - # yield - # except CancelledError as er: - # # cancel all waiting tasks - # raise er - ts[i] = await ts[i] - except (core.CancelledError, Exception) as er: - if return_exceptions: - ts[i] = er - else: - raise er - return ts diff --git a/extmod/uasyncio/lock.py b/extmod/uasyncio/lock.py deleted file mode 100644 index bddca295b6af0..0000000000000 --- a/extmod/uasyncio/lock.py +++ /dev/null @@ -1,53 +0,0 @@ -# MicroPython uasyncio module -# MIT license; Copyright (c) 2019-2020 Damien P. George - -from . import core - -# Lock class for primitive mutex capability -class Lock: - def __init__(self): - # The state can take the following values: - # - 0: unlocked - # - 1: locked - # - : unlocked but this task has been scheduled to acquire the lock next - self.state = 0 - # Queue of Tasks waiting to acquire this Lock - self.waiting = core.TaskQueue() - - def locked(self): - return self.state == 1 - - def release(self): - if self.state != 1: - raise RuntimeError("Lock not acquired") - if self.waiting.peek(): - # Task(s) waiting on lock, schedule next Task - self.state = self.waiting.pop_head() - core._task_queue.push_head(self.state) - else: - # No Task waiting so unlock - self.state = 0 - - async def acquire(self): - if self.state != 0: - # Lock unavailable, put the calling Task on the waiting queue - self.waiting.push_head(core.cur_task) - # Set calling task's data to the lock's queue so it can be removed if needed - core.cur_task.data = self.waiting - try: - yield - except core.CancelledError as er: - if self.state == core.cur_task: - # Cancelled while pending on resume, schedule next waiting Task - self.state = 1 - self.release() - raise er - # Lock available, set it as locked - self.state = 1 - return True - - async def __aenter__(self): - return await self.acquire() - - async def __aexit__(self, exc_type, exc, tb): - return self.release() diff --git a/extmod/uasyncio/manifest.py b/extmod/uasyncio/manifest.py deleted file mode 100644 index f5fa27bfcaa35..0000000000000 --- a/extmod/uasyncio/manifest.py +++ /dev/null @@ -1,13 +0,0 @@ -# This list of frozen files doesn't include task.py because that's provided by the C module. -freeze( - "..", - ( - "uasyncio/__init__.py", - "uasyncio/core.py", - "uasyncio/event.py", - "uasyncio/funcs.py", - "uasyncio/lock.py", - "uasyncio/stream.py", - ), - opt=3, -) diff --git a/extmod/uasyncio/stream.py b/extmod/uasyncio/stream.py deleted file mode 100644 index af3b8feab3588..0000000000000 --- a/extmod/uasyncio/stream.py +++ /dev/null @@ -1,164 +0,0 @@ -# MicroPython uasyncio module -# MIT license; Copyright (c) 2019-2020 Damien P. George - -from . import core - - -class Stream: - def __init__(self, s, e={}): - self.s = s - self.e = e - self.out_buf = b"" - - def get_extra_info(self, v): - return self.e[v] - - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - await self.close() - - def close(self): - pass - - async def wait_closed(self): - # TODO yield? - self.s.close() - - async def read(self, n): - yield core._io_queue.queue_read(self.s) - return self.s.read(n) - - async def readinto(self, buf): - yield core._io_queue.queue_read(self.s) - return self.s.readinto(buf) - - async def readexactly(self, n): - r = b"" - while n: - yield core._io_queue.queue_read(self.s) - r2 = self.s.read(n) - if r2 is not None: - if not len(r2): - raise EOFError - r += r2 - n -= len(r2) - return r - - async def readline(self): - l = b"" - while True: - yield core._io_queue.queue_read(self.s) - l2 = self.s.readline() # may do multiple reads but won't block - l += l2 - if not l2 or l[-1] == 10: # \n (check l in case l2 is str) - return l - - def write(self, buf): - self.out_buf += buf - - async def drain(self): - mv = memoryview(self.out_buf) - off = 0 - while off < len(mv): - yield core._io_queue.queue_write(self.s) - ret = self.s.write(mv[off:]) - if ret is not None: - off += ret - self.out_buf = b"" - - -# Stream can be used for both reading and writing to save code size -StreamReader = Stream -StreamWriter = Stream - - -# Create a TCP stream connection to a remote host -async def open_connection(host, port): - from uerrno import EINPROGRESS - import usocket as socket - - ai = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM)[0] # TODO this is blocking! - s = socket.socket(ai[0], ai[1], ai[2]) - s.setblocking(False) - ss = Stream(s) - try: - s.connect(ai[-1]) - except OSError as er: - if er.errno != EINPROGRESS: - raise er - yield core._io_queue.queue_write(s) - return ss, ss - - -# Class representing a TCP stream server, can be closed and used in "async with" -class Server: - async def __aenter__(self): - return self - - async def __aexit__(self, exc_type, exc, tb): - self.close() - await self.wait_closed() - - def close(self): - self.task.cancel() - - async def wait_closed(self): - await self.task - - async def _serve(self, s, cb): - # Accept incoming connections - while True: - try: - yield core._io_queue.queue_read(s) - except core.CancelledError: - # Shutdown server - s.close() - return - try: - s2, addr = s.accept() - except: - # Ignore a failed accept - continue - s2.setblocking(False) - s2s = Stream(s2, {"peername": addr}) - core.create_task(cb(s2s, s2s)) - - -# Helper function to start a TCP stream server, running as a new task -# TODO could use an accept-callback on socket read activity instead of creating a task -async def start_server(cb, host, port, backlog=5): - import usocket as socket - - # Create and bind server socket. - host = socket.getaddrinfo(host, port)[0] # TODO this is blocking! - s = socket.socket() - s.setblocking(False) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - s.bind(host[-1]) - s.listen(backlog) - - # Create and return server object and task. - srv = Server() - srv.task = core.create_task(srv._serve(s, cb)) - return srv - - -################################################################################ -# Legacy uasyncio compatibility - - -async def stream_awrite(self, buf, off=0, sz=-1): - if off != 0 or sz != -1: - buf = memoryview(buf) - if sz == -1: - sz = len(buf) - buf = buf[off : off + sz] - self.write(buf) - await self.drain() - - -Stream.aclose = Stream.wait_closed -Stream.awrite = stream_awrite -Stream.awritestr = stream_awrite # TODO explicitly convert to bytes? diff --git a/extmod/uasyncio/task.py b/extmod/uasyncio/task.py deleted file mode 100644 index 7a80b25208019..0000000000000 --- a/extmod/uasyncio/task.py +++ /dev/null @@ -1,179 +0,0 @@ -# MicroPython uasyncio module -# MIT license; Copyright (c) 2019-2020 Damien P. George - -# This file contains the core TaskQueue based on a pairing heap, and the core Task class. -# They can optionally be replaced by C implementations. - -from . import core - - -# pairing-heap meld of 2 heaps; O(1) -def ph_meld(h1, h2): - if h1 is None: - return h2 - if h2 is None: - return h1 - lt = core.ticks_diff(h1.ph_key, h2.ph_key) < 0 - if lt: - if h1.ph_child is None: - h1.ph_child = h2 - else: - h1.ph_child_last.ph_next = h2 - h1.ph_child_last = h2 - h2.ph_next = None - h2.ph_rightmost_parent = h1 - return h1 - else: - h1.ph_next = h2.ph_child - h2.ph_child = h1 - if h1.ph_next is None: - h2.ph_child_last = h1 - h1.ph_rightmost_parent = h2 - return h2 - - -# pairing-heap pairing operation; amortised O(log N) -def ph_pairing(child): - heap = None - while child is not None: - n1 = child - child = child.ph_next - n1.ph_next = None - if child is not None: - n2 = child - child = child.ph_next - n2.ph_next = None - n1 = ph_meld(n1, n2) - heap = ph_meld(heap, n1) - return heap - - -# pairing-heap delete of a node; stable, amortised O(log N) -def ph_delete(heap, node): - if node is heap: - child = heap.ph_child - node.ph_child = None - return ph_pairing(child) - # Find parent of node - parent = node - while parent.ph_next is not None: - parent = parent.ph_next - parent = parent.ph_rightmost_parent - # Replace node with pairing of its children - if node is parent.ph_child and node.ph_child is None: - parent.ph_child = node.ph_next - node.ph_next = None - return heap - elif node is parent.ph_child: - child = node.ph_child - next = node.ph_next - node.ph_child = None - node.ph_next = None - node = ph_pairing(child) - parent.ph_child = node - else: - n = parent.ph_child - while node is not n.ph_next: - n = n.ph_next - child = node.ph_child - next = node.ph_next - node.ph_child = None - node.ph_next = None - node = ph_pairing(child) - if node is None: - node = n - else: - n.ph_next = node - node.ph_next = next - if next is None: - node.ph_rightmost_parent = parent - parent.ph_child_last = node - return heap - - -# TaskQueue class based on the above pairing-heap functions. -class TaskQueue: - def __init__(self): - self.heap = None - - def peek(self): - return self.heap - - def push_sorted(self, v, key): - v.data = None - v.ph_key = key - v.ph_child = None - v.ph_next = None - self.heap = ph_meld(v, self.heap) - - def push_head(self, v): - self.push_sorted(v, core.ticks()) - - def pop_head(self): - v = self.heap - self.heap = ph_pairing(self.heap.ph_child) - return v - - def remove(self, v): - self.heap = ph_delete(self.heap, v) - - -# Task class representing a coroutine, can be waited on and cancelled. -class Task: - def __init__(self, coro, globals=None): - self.coro = coro # Coroutine of this Task - self.data = None # General data for queue it is waiting on - self.state = True # None, False, True or a TaskQueue instance - self.ph_key = 0 # Pairing heap - self.ph_child = None # Paring heap - self.ph_child_last = None # Paring heap - self.ph_next = None # Paring heap - self.ph_rightmost_parent = None # Paring heap - - def __await__(self): - if not self.state: - # Task finished, signal that is has been await'ed on. - self.state = False - elif self.state is True: - # Allocated head of linked list of Tasks waiting on completion of this task. - self.state = TaskQueue() - return self - - def __next__(self): - if not self.state: - if self.data is None: - # Task finished but has already been sent to the loop's exception handler. - raise StopIteration - else: - # Task finished, raise return value to caller so it can continue. - raise self.data - else: - # Put calling task on waiting queue. - self.state.push_head(core.cur_task) - # Set calling task's data to this task that it waits on, to double-link it. - core.cur_task.data = self - - def done(self): - return not self.state - - def cancel(self): - # Check if task is already finished. - if not self.state: - return False - # Can't cancel self (not supported yet). - if self is core.cur_task: - raise RuntimeError("can't cancel self") - # If Task waits on another task then forward the cancel to the one it's waiting on. - while isinstance(self.data, Task): - self = self.data - # Reschedule Task as a cancelled task. - if hasattr(self.data, "remove"): - # Not on the main running queue, remove the task from the queue it's on. - self.data.remove(self) - core._task_queue.push_head(self) - elif core.ticks_diff(self.ph_key, core.ticks()) > 0: - # On the main running queue but scheduled in the future, so bring it forward to now. - core._task_queue.remove(self) - core._task_queue.push_head(self) - self.data = core.CancelledError - return True diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c index 0d6437a92049c..3d1cdfd820629 100644 --- a/extmod/utime_mphal.c +++ b/extmod/utime_mphal.c @@ -1,8 +1,29 @@ -// Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/mpconfig.h" #if MICROPY_PY_UTIME_MP_HAL diff --git a/extmod/utime_mphal.h b/extmod/utime_mphal.h index 61a851cec0f50..57fc348832812 100644 --- a/extmod/utime_mphal.h +++ b/extmod/utime_mphal.h @@ -1,9 +1,29 @@ -// Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George -// -// SPDX-License-Identifier: MIT - +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H #define MICROPY_INCLUDED_EXTMOD_UTIME_MPHAL_H diff --git a/extmod/vfs.c b/extmod/vfs.c index 7aa82a6082446..61d85b293bbf0 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include @@ -386,8 +407,7 @@ mp_obj_t mp_vfs_ilistdir(size_t n_args, const mp_obj_t *args) { if (vfs == MP_VFS_ROOT) { // list the root directory - mp_vfs_ilistdir_it_t *iter = m_new_obj(mp_vfs_ilistdir_it_t); - iter->base.type = &mp_type_polymorph_iter; + mp_vfs_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_ilistdir_it_t, &mp_type_polymorph_iter); iter->iternext = mp_vfs_ilistdir_it_iternext; iter->cur.vfs = MP_STATE_VM(vfs_mount_table); iter->is_str = mp_obj_get_type(path_in) == &mp_type_str; diff --git a/extmod/vfs.h b/extmod/vfs.h index abb563e9a98e7..49c6d87e58afb 100644 --- a/extmod/vfs.h +++ b/extmod/vfs.h @@ -1,12 +1,32 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George -// -// SPDX-License-Identifier: MIT - +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef MICROPY_INCLUDED_EXTMOD_VFS_H #define MICROPY_INCLUDED_EXTMOD_VFS_H -#include "py/lexer.h" +#include "py/builtin.h" #include "py/obj.h" #include "py/proto.h" diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 0a9737e53a942..4d4e7e881ae82 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -1,8 +1,29 @@ -// Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/mpconfig.h" #if MICROPY_VFS_FAT @@ -54,8 +75,7 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_ mp_arg_check_num(n_args, n_kw, 1, 1, false); // create new object - fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t); - vfs->base.type = type; + fs_user_mount_t *vfs = mp_obj_malloc(fs_user_mount_t, type); vfs->fatfs.drv = vfs; // Initialise underlying block device @@ -171,8 +191,7 @@ STATIC mp_obj_t fat_vfs_ilistdir_func(size_t n_args, const mp_obj_t *args) { } // Create a new iterator object to list the dir - mp_vfs_fat_ilistdir_it_t *iter = m_new_obj(mp_vfs_fat_ilistdir_it_t); - iter->base.type = &mp_type_polymorph_iter; + mp_vfs_fat_ilistdir_it_t *iter = mp_obj_malloc(mp_vfs_fat_ilistdir_it_t, &mp_type_polymorph_iter); iter->iternext = mp_vfs_fat_ilistdir_it_iternext; iter->is_str = is_str_type; FRESULT res = f_opendir(&self->fatfs, &iter->dir, path); diff --git a/extmod/vfs_fat.h b/extmod/vfs_fat.h index d64aaf30a2554..cd003e2fe1887 100644 --- a/extmod/vfs_fat.h +++ b/extmod/vfs_fat.h @@ -1,8 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George -// -// SPDX-License-Identifier: MIT - +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef MICROPY_INCLUDED_EXTMOD_VFS_FAT_H #define MICROPY_INCLUDED_EXTMOD_VFS_FAT_H diff --git a/extmod/vfs_fat_diskio.c b/extmod/vfs_fat_diskio.c index 9561a6740b2d5..1bcd471f2162e 100644 --- a/extmod/vfs_fat_diskio.c +++ b/extmod/vfs_fat_diskio.c @@ -1,7 +1,31 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * Original template for this file comes from: + * Low level disk I/O module skeleton for FatFs, (C)ChaN, 2013 + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/mpconfig.h" #if MICROPY_VFS && MICROPY_VFS_FAT diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c index 2415f7d3c14c7..36070f1011431 100644 --- a/extmod/vfs_fat_file.c +++ b/extmod/vfs_fat_file.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/mpconfig.h" #if MICROPY_VFS && MICROPY_VFS_FAT @@ -136,6 +157,7 @@ STATIC const mp_arg_t file_open_args[] = { }; #define FILE_OPEN_NUM_ARGS MP_ARRAY_SIZE(file_open_args) +// CIRCUITPY is more careful about validating the open mode. STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_arg_val_t *args) { int mode = 0; const char *mode_s = mp_obj_str_get_str(args[1].u_obj); @@ -210,7 +232,7 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar DWORD size = (temp_table[0] + 1) * 2; // Now allocate the size and construct the map. - o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD), false); + o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD)); if (o->fp.cltbl != NULL) { o->fp.cltbl[0] = size; res = f_lseek(&o->fp, CREATE_LINKMAP); diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index 872d7f8428b64..0cd3295fafa99 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -203,8 +203,7 @@ STATIC mp_obj_t MP_VFS_LFSx(ilistdir_func)(size_t n_args, const mp_obj_t *args) path = vstr_null_terminated_str(&self->cur_dir); } - MP_VFS_LFSx(ilistdir_it_t) * iter = m_new_obj(MP_VFS_LFSx(ilistdir_it_t)); - iter->base.type = &mp_type_polymorph_iter; + MP_VFS_LFSx(ilistdir_it_t) * iter = mp_obj_malloc(MP_VFS_LFSx(ilistdir_it_t), &mp_type_polymorph_iter); iter->iternext = MP_VFS_LFSx(ilistdir_it_iternext); iter->is_str = is_str_type; iter->vfs = self; diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index 1d0aa09664774..4e73acea6f0ec 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2017-2018 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017-2018 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/runtime.h" #include "py/mperrno.h" @@ -16,6 +37,9 @@ #include #include #include +#ifdef _MSC_VER +#include // For mkdir etc. +#endif typedef struct _mp_obj_vfs_posix_t { mp_obj_base_t base; @@ -74,8 +98,7 @@ STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - mp_obj_vfs_posix_t *vfs = m_new_obj(mp_obj_vfs_posix_t); - vfs->base.type = type; + mp_obj_vfs_posix_t *vfs = mp_obj_malloc(mp_obj_vfs_posix_t, type); vstr_init(&vfs->root, 0); if (n_args == 1) { vstr_add_str(&vfs->root, mp_obj_str_get_str(args[0])); @@ -205,8 +228,7 @@ STATIC mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) { STATIC mp_obj_t vfs_posix_ilistdir(mp_obj_t self_in, mp_obj_t path_in) { mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); - vfs_posix_ilistdir_it_t *iter = m_new_obj(vfs_posix_ilistdir_it_t); - iter->base.type = &mp_type_polymorph_iter; + vfs_posix_ilistdir_it_t *iter = mp_obj_malloc(vfs_posix_ilistdir_it_t, &mp_type_polymorph_iter); iter->iternext = vfs_posix_ilistdir_it_iternext; iter->is_str = mp_obj_get_type(path_in) == &mp_type_str; const char *path = vfs_posix_get_path_str(self, path_in); @@ -233,7 +255,11 @@ STATIC mp_obj_t vfs_posix_mkdir(mp_obj_t self_in, mp_obj_t path_in) { mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); const char *path = vfs_posix_get_path_str(self, path_in); MP_THREAD_GIL_EXIT(); + #ifdef _WIN32 + int ret = mkdir(path); + #else int ret = mkdir(path, 0777); + #endif MP_THREAD_GIL_ENTER(); if (ret != 0) { mp_raise_OSError(errno); @@ -287,6 +313,8 @@ STATIC mp_obj_t vfs_posix_stat(mp_obj_t self_in, mp_obj_t path_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_stat_obj, vfs_posix_stat); +#if MICROPY_PY_UOS_STATVFS + #ifdef __ANDROID__ #define USE_STATFS 1 #endif @@ -328,6 +356,8 @@ STATIC mp_obj_t vfs_posix_statvfs(mp_obj_t self_in, mp_obj_t path_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_statvfs_obj, vfs_posix_statvfs); +#endif + STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_posix_mount_obj) }, { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&vfs_posix_umount_obj) }, @@ -341,7 +371,9 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&vfs_posix_rename_obj) }, { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&vfs_posix_rmdir_obj) }, { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_posix_stat_obj) }, + #if MICROPY_PY_UOS_STATVFS { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_posix_statvfs_obj) }, + #endif }; STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table); diff --git a/extmod/vfs_posix.h b/extmod/vfs_posix.h index 4540baedf060c..32299b8269f07 100644 --- a/extmod/vfs_posix.h +++ b/extmod/vfs_posix.h @@ -1,8 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2018 Damien P. George -// -// SPDX-License-Identifier: MIT - +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H #define MICROPY_INCLUDED_EXTMOD_VFS_POSIX_H diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index 94ddbe5f7be13..534b11c08c5c3 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013-2018 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2018 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "py/mphal.h" #include "py/mpthread.h" diff --git a/extmod/vfs_reader.c b/extmod/vfs_reader.c index c87fcd76fdf0d..d3904c5c50693 100644 --- a/extmod/vfs_reader.c +++ b/extmod/vfs_reader.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2017 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include diff --git a/extmod/virtpin.c b/extmod/virtpin.c index e19c05c8128b9..510ba8dbafd35 100644 --- a/extmod/virtpin.c +++ b/extmod/virtpin.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include "extmod/virtpin.h" #include "py/proto.h" diff --git a/extmod/virtpin.h b/extmod/virtpin.h index 9b43406bd1e14..591249e48d670 100644 --- a/extmod/virtpin.h +++ b/extmod/virtpin.h @@ -1,8 +1,28 @@ -// Copyright (c) 2016 Paul Sokolovsky -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT - +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #ifndef MICROPY_INCLUDED_EXTMOD_VIRTPIN_H #define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H diff --git a/frozen/Adafruit_CircuitPython_APDS9960 b/frozen/Adafruit_CircuitPython_APDS9960 index 2582575b50054..9ddd59650598b 160000 --- a/frozen/Adafruit_CircuitPython_APDS9960 +++ b/frozen/Adafruit_CircuitPython_APDS9960 @@ -1 +1 @@ -Subproject commit 2582575b500547f26dae04c83e540367c121c7b4 +Subproject commit 9ddd59650598b7a0641d70aabcc8aab71799cb93 diff --git a/frozen/Adafruit_CircuitPython_BLE b/frozen/Adafruit_CircuitPython_BLE index f32e7b953ec93..e07e1853d7e99 160000 --- a/frozen/Adafruit_CircuitPython_BLE +++ b/frozen/Adafruit_CircuitPython_BLE @@ -1 +1 @@ -Subproject commit f32e7b953ec93f71fcb292074b6d25c7c4355a88 +Subproject commit e07e1853d7e995b9797a064c098bccc5c384632e diff --git a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center index 8455eb0b1f5be..b06b47037aed9 160000 --- a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center +++ b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center @@ -1 +1 @@ -Subproject commit 8455eb0b1f5be39638a88df84c9ab360f50ecc90 +Subproject commit b06b47037aed97475b1676b104d1f4b05c3f5e86 diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index 14f5a0b957a11..9ace770b048be 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit 14f5a0b957a11814339f0e22896243fecc9a78f2 +Subproject commit 9ace770b048be9ab0da4a154af279dbb643bbdb0 diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index bdf4373d734a5..47f848f13f75d 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit bdf4373d734a5c000ef500f70c94b5b24d2663af +Subproject commit 47f848f13f75d2f62d16407edaaf6dd0ec1fc3cc diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index a1f6652943723..a37c7cc83685f 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit a1f66529437232d85dbbd3ce7d9688357966cc26 +Subproject commit a37c7cc83685f2ff84a171a519207567a75d0947 diff --git a/frozen/Adafruit_CircuitPython_DRV2605 b/frozen/Adafruit_CircuitPython_DRV2605 index 547a7d2a738ee..ab0ffa938dfa7 160000 --- a/frozen/Adafruit_CircuitPython_DRV2605 +++ b/frozen/Adafruit_CircuitPython_DRV2605 @@ -1 +1 @@ -Subproject commit 547a7d2a738eeee18e511d71505a645915094395 +Subproject commit ab0ffa938dfa7eb1fd7260353a7a4e28f55e537a diff --git a/frozen/Adafruit_CircuitPython_DS3231 b/frozen/Adafruit_CircuitPython_DS3231 index fc3a6a651ee62..e6a9a0140ed44 160000 --- a/frozen/Adafruit_CircuitPython_DS3231 +++ b/frozen/Adafruit_CircuitPython_DS3231 @@ -1 +1 @@ -Subproject commit fc3a6a651ee6211b02903ec0bc6808b359bf6d4b +Subproject commit e6a9a0140ed44ef5f15d8040fce35b5319c1f216 diff --git a/frozen/Adafruit_CircuitPython_Display_Shapes b/frozen/Adafruit_CircuitPython_Display_Shapes index 12beb94e4758d..cf2b173d0fc3a 160000 --- a/frozen/Adafruit_CircuitPython_Display_Shapes +++ b/frozen/Adafruit_CircuitPython_Display_Shapes @@ -1 +1 @@ -Subproject commit 12beb94e4758d6d0f4965b731b086a1bf8c3704e +Subproject commit cf2b173d0fc3ac2cd961754c6adf8f614a1c7c39 diff --git a/frozen/Adafruit_CircuitPython_Display_Text b/frozen/Adafruit_CircuitPython_Display_Text index c8bc5431f9ac2..911201504a269 160000 --- a/frozen/Adafruit_CircuitPython_Display_Text +++ b/frozen/Adafruit_CircuitPython_Display_Text @@ -1 +1 @@ -Subproject commit c8bc5431f9ac20ca5b40d0760ac407368d640c4d +Subproject commit 911201504a269dbfc49b04ca59bc54adabd4716a diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index 67f8c35e2ce4a..187279a95e5cd 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit 67f8c35e2ce4a8abc3cfb24ab5029b40a64857b8 +Subproject commit 187279a95e5cdd634d233af59352558cea4c1227 diff --git a/frozen/Adafruit_CircuitPython_ESP32SPI b/frozen/Adafruit_CircuitPython_ESP32SPI index c8bb6258a0444..ee6bfcf9e676e 160000 --- a/frozen/Adafruit_CircuitPython_ESP32SPI +++ b/frozen/Adafruit_CircuitPython_ESP32SPI @@ -1 +1 @@ -Subproject commit c8bb6258a0444c31ab5ae69e3af1fffbd7761a99 +Subproject commit ee6bfcf9e676eb435c8890db37f07719984a60a1 diff --git a/frozen/Adafruit_CircuitPython_FakeRequests b/frozen/Adafruit_CircuitPython_FakeRequests index bf7763ef99ca0..8eedf860beca0 160000 --- a/frozen/Adafruit_CircuitPython_FakeRequests +++ b/frozen/Adafruit_CircuitPython_FakeRequests @@ -1 +1 @@ -Subproject commit bf7763ef99ca00d1808a9aa47bb1d593a2cc0334 +Subproject commit 8eedf860beca0d32219189b72ea6fc8eea7e66db diff --git a/frozen/Adafruit_CircuitPython_FocalTouch b/frozen/Adafruit_CircuitPython_FocalTouch index 5e4d371d210bb..3d7d404a1cafc 160000 --- a/frozen/Adafruit_CircuitPython_FocalTouch +++ b/frozen/Adafruit_CircuitPython_FocalTouch @@ -1 +1 @@ -Subproject commit 5e4d371d210bbe00e63f83ce698f5bfa8652fa51 +Subproject commit 3d7d404a1cafc02f6c3391b100157490132e5c5f diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID index 9ec404f8b318a..93c7e0ed55e7e 160000 --- a/frozen/Adafruit_CircuitPython_HID +++ b/frozen/Adafruit_CircuitPython_HID @@ -1 +1 @@ -Subproject commit 9ec404f8b318af5b4f02855311e5a00233ce29b5 +Subproject commit 93c7e0ed55e7ed011908ac9a1c0f8228f0f4323b diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index fc377ac4050c9..340c62ef6ce86 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit fc377ac4050c95eb8ea5eeacb8b68ef0d6152abb +Subproject commit 340c62ef6ce867b3924d166afc3d2a171680f799 diff --git a/frozen/Adafruit_CircuitPython_IS31FL3731 b/frozen/Adafruit_CircuitPython_IS31FL3731 index 31a6a9b69e751..5433ba3760ca6 160000 --- a/frozen/Adafruit_CircuitPython_IS31FL3731 +++ b/frozen/Adafruit_CircuitPython_IS31FL3731 @@ -1 +1 @@ -Subproject commit 31a6a9b69e75144bdf29377b95f52213dab83e8a +Subproject commit 5433ba3760ca605267223de883a44cb8394f40a5 diff --git a/frozen/Adafruit_CircuitPython_LC709203F b/frozen/Adafruit_CircuitPython_LC709203F index 02b4bacba30d0..38bd02f014403 160000 --- a/frozen/Adafruit_CircuitPython_LC709203F +++ b/frozen/Adafruit_CircuitPython_LC709203F @@ -1 +1 @@ -Subproject commit 02b4bacba30d029422e1df49be917e89f496067d +Subproject commit 38bd02f014403954ab52154e3877e502d83862dc diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index 6791d3fe75123..240fe51935f4a 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit 6791d3fe751239acbfc8dc293652b068f0dcc2f6 +Subproject commit 240fe51935f4a9def33ef347d40b13862a60b7ac diff --git a/frozen/Adafruit_CircuitPython_LSM6DS b/frozen/Adafruit_CircuitPython_LSM6DS index 691fefb26458b..d689ca77c6780 160000 --- a/frozen/Adafruit_CircuitPython_LSM6DS +++ b/frozen/Adafruit_CircuitPython_LSM6DS @@ -1 +1 @@ -Subproject commit 691fefb26458b872520988acf315ad72fd67798d +Subproject commit d689ca77c67806484037e00110c669cf55846b6e diff --git a/frozen/Adafruit_CircuitPython_MIDI b/frozen/Adafruit_CircuitPython_MIDI index c572416239621..e38bf1f9cf1e8 160000 --- a/frozen/Adafruit_CircuitPython_MIDI +++ b/frozen/Adafruit_CircuitPython_MIDI @@ -1 +1 @@ -Subproject commit c572416239621066656c18dd88ee69ce383cfff5 +Subproject commit e38bf1f9cf1e8faeb7d15a1d10674fb2c0a81e72 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index cc5fa11ceb68a..9c3de3abce00b 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit cc5fa11ceb68af5597f6a308fed5d9c8480c32a3 +Subproject commit 9c3de3abce00b50ba936f4f8daad0a8a6bee34a6 diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel index 8211388d13f21..9516aa97e9216 160000 --- a/frozen/Adafruit_CircuitPython_NeoPixel +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -1 +1 @@ -Subproject commit 8211388d13f216a3933e7dc896c1fe054edc7bed +Subproject commit 9516aa97e9216eac2b229fbb7dac34fa60c347c4 diff --git a/frozen/Adafruit_CircuitPython_PortalBase b/frozen/Adafruit_CircuitPython_PortalBase index 98d1d12b79674..759c5c3488789 160000 --- a/frozen/Adafruit_CircuitPython_PortalBase +++ b/frozen/Adafruit_CircuitPython_PortalBase @@ -1 +1 @@ -Subproject commit 98d1d12b79674e5e7722dcc31123ba990e3e83f7 +Subproject commit 759c5c348878932adc5fcc9e4f3b3f570b43e17f diff --git a/frozen/Adafruit_CircuitPython_ProgressBar b/frozen/Adafruit_CircuitPython_ProgressBar index 80501daf8f0cd..74a1c261103cd 160000 --- a/frozen/Adafruit_CircuitPython_ProgressBar +++ b/frozen/Adafruit_CircuitPython_ProgressBar @@ -1 +1 @@ -Subproject commit 80501daf8f0cd7710d53f107a13821f63875a874 +Subproject commit 74a1c261103cda43172053ff2370777255b9bf8d diff --git a/frozen/Adafruit_CircuitPython_RFM69 b/frozen/Adafruit_CircuitPython_RFM69 index 34c48e70f4209..af1cba8a7e4e3 160000 --- a/frozen/Adafruit_CircuitPython_RFM69 +++ b/frozen/Adafruit_CircuitPython_RFM69 @@ -1 +1 @@ -Subproject commit 34c48e70f4209c363dac65d1a265ce9bb819c0a3 +Subproject commit af1cba8a7e4e3950fcc5367e9c55a024d9ab9f64 diff --git a/frozen/Adafruit_CircuitPython_RFM9x b/frozen/Adafruit_CircuitPython_RFM9x index 769bcbfe4bc43..c46c59e300481 160000 --- a/frozen/Adafruit_CircuitPython_RFM9x +++ b/frozen/Adafruit_CircuitPython_RFM9x @@ -1 +1 @@ -Subproject commit 769bcbfe4bc4366ab59958ca3042ded0029362ce +Subproject commit c46c59e3004817c708c78c59d247b02161c6bf06 diff --git a/frozen/Adafruit_CircuitPython_Register b/frozen/Adafruit_CircuitPython_Register index 59ebc1930d1e8..46a49205f3f14 160000 --- a/frozen/Adafruit_CircuitPython_Register +++ b/frozen/Adafruit_CircuitPython_Register @@ -1 +1 @@ -Subproject commit 59ebc1930d1e82b9a5a82e855077151ff6454fe2 +Subproject commit 46a49205f3f14546273dd1267e66cad82f03986c diff --git a/frozen/Adafruit_CircuitPython_Requests b/frozen/Adafruit_CircuitPython_Requests index 36f1bb0f1b739..558fff7223178 160000 --- a/frozen/Adafruit_CircuitPython_Requests +++ b/frozen/Adafruit_CircuitPython_Requests @@ -1 +1 @@ -Subproject commit 36f1bb0f1b739a06b7e2782580ce08eecf17c78a +Subproject commit 558fff7223178eae6228e5262f3a08d3a4101394 diff --git a/frozen/Adafruit_CircuitPython_SD b/frozen/Adafruit_CircuitPython_SD index 5537f452959b4..eb17bffa757dc 160000 --- a/frozen/Adafruit_CircuitPython_SD +++ b/frozen/Adafruit_CircuitPython_SD @@ -1 +1 @@ -Subproject commit 5537f452959b4f2d44742f24808fac7f7098c03d +Subproject commit eb17bffa757dc8c0a53fe9e61c45246c06418099 diff --git a/frozen/Adafruit_CircuitPython_SSD1680 b/frozen/Adafruit_CircuitPython_SSD1680 index 916bf37b9270d..91b6867aca2b0 160000 --- a/frozen/Adafruit_CircuitPython_SSD1680 +++ b/frozen/Adafruit_CircuitPython_SSD1680 @@ -1 +1 @@ -Subproject commit 916bf37b9270dfd60596a455e1405de01150397b +Subproject commit 91b6867aca2b0511571fed14ab051d37f1f1544c diff --git a/frozen/Adafruit_CircuitPython_ST7789 b/frozen/Adafruit_CircuitPython_ST7789 index d939bbf9395a2..e23c4871456cd 160000 --- a/frozen/Adafruit_CircuitPython_ST7789 +++ b/frozen/Adafruit_CircuitPython_ST7789 @@ -1 +1 @@ -Subproject commit d939bbf9395a27d3200d12de333d7c78956a80a4 +Subproject commit e23c4871456cdf0ef1bfb59d1c2f6e38b7b640ee diff --git a/frozen/Adafruit_CircuitPython_SimpleIO b/frozen/Adafruit_CircuitPython_SimpleIO index 6897d6ff21132..eac33b430b0cb 160000 --- a/frozen/Adafruit_CircuitPython_SimpleIO +++ b/frozen/Adafruit_CircuitPython_SimpleIO @@ -1 +1 @@ -Subproject commit 6897d6ff21132e99111c72b2e60cf1d20223e9bb +Subproject commit eac33b430b0cbe1f6f583000f6b29f75bfe8507e diff --git a/frozen/Adafruit_CircuitPython_SimpleMath b/frozen/Adafruit_CircuitPython_SimpleMath index d85c19bf00e01..dc605bb22914d 160000 --- a/frozen/Adafruit_CircuitPython_SimpleMath +++ b/frozen/Adafruit_CircuitPython_SimpleMath @@ -1 +1 @@ -Subproject commit d85c19bf00e01f32382b1ef0ad9218bea4b6b234 +Subproject commit dc605bb22914d77d80c5342cbb4c10f773aede95 diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index 16e712f385526..43a4f15d60491 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit 16e712f385526f2edbdf37394addf764cea35f29 +Subproject commit 43a4f15d604919d6e143e975a85abf7b96a4061d diff --git a/frozen/Adafruit_CircuitPython_Ticks b/frozen/Adafruit_CircuitPython_Ticks index 1542544d27748..2634ca0163020 160000 --- a/frozen/Adafruit_CircuitPython_Ticks +++ b/frozen/Adafruit_CircuitPython_Ticks @@ -1 +1 @@ -Subproject commit 1542544d2774895c4d9ef732f851b8a40796fe5c +Subproject commit 2634ca0163020bebec300fcca6e0b5afcdc655b8 diff --git a/frozen/Adafruit_CircuitPython_UC8151D b/frozen/Adafruit_CircuitPython_UC8151D index b9a599ae279f5..b6d9f852f50b4 160000 --- a/frozen/Adafruit_CircuitPython_UC8151D +++ b/frozen/Adafruit_CircuitPython_UC8151D @@ -1 +1 @@ -Subproject commit b9a599ae279f560d434206b947e3353e9c35bbea +Subproject commit b6d9f852f50b489615f3f357f9758d0073335334 diff --git a/frozen/Adafruit_CircuitPython_Wave b/frozen/Adafruit_CircuitPython_Wave index c4c4453f9a709..02b748f2e6826 160000 --- a/frozen/Adafruit_CircuitPython_Wave +++ b/frozen/Adafruit_CircuitPython_Wave @@ -1 +1 @@ -Subproject commit c4c4453f9a7097df2683cf29341cb2d9e1167da6 +Subproject commit 02b748f2e6826dc442c842885e58b07ad10d9287 diff --git a/frozen/Adafruit_CircuitPython_asyncio b/frozen/Adafruit_CircuitPython_asyncio index 18a411eb8749b..7c25d09be04a2 160000 --- a/frozen/Adafruit_CircuitPython_asyncio +++ b/frozen/Adafruit_CircuitPython_asyncio @@ -1 +1 @@ -Subproject commit 18a411eb8749b8de94dcd9ddd0a2863f3ff17622 +Subproject commit 7c25d09be04a2979bcfb43b801de57594112808d diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index b317568508d67..d4ff0388f3e3a 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit b317568508d67ed07f8078b9f941cf72945859fe +Subproject commit d4ff0388f3e3af2745864f2c3e5926f500673a40 diff --git a/lib/littlefs/lfs2.c b/lib/littlefs/lfs2.c index 39bd2f0d1c94f..534e4a1a65512 100644 --- a/lib/littlefs/lfs2.c +++ b/lib/littlefs/lfs2.c @@ -1,16 +1,33 @@ /* * The little filesystem * + * Copyright (c) 2022, The littlefs authors. * Copyright (c) 2017, Arm Limited. All rights reserved. * SPDX-License-Identifier: BSD-3-Clause */ #include "lfs2.h" #include "lfs2_util.h" + +// some constants used throughout the code #define LFS2_BLOCK_NULL ((lfs2_block_t)-1) #define LFS2_BLOCK_INLINE ((lfs2_block_t)-2) +enum { + LFS2_OK_RELOCATED = 1, + LFS2_OK_DROPPED = 2, + LFS2_OK_ORPHANED = 3, +}; + +enum { + LFS2_CMP_EQ = 0, + LFS2_CMP_LT = 1, + LFS2_CMP_GT = 2, +}; + + /// Caching block device operations /// + static inline void lfs2_cache_drop(lfs2_t *lfs2, lfs2_cache_t *rcache) { // do not zero, cheaper if cache is readonly or only going to be // written with identical data (during relocates) @@ -107,12 +124,6 @@ static int lfs2_bd_read(lfs2_t *lfs2, return 0; } -enum { - LFS2_CMP_EQ = 0, - LFS2_CMP_LT = 1, - LFS2_CMP_GT = 2, -}; - static int lfs2_bd_cmp(lfs2_t *lfs2, const lfs2_cache_t *pcache, lfs2_cache_t *rcache, lfs2_size_t hint, lfs2_block_t block, lfs2_off_t off, @@ -268,22 +279,26 @@ static inline int lfs2_pair_cmp( paira[0] == pairb[1] || paira[1] == pairb[0]); } +#ifndef LFS2_READONLY static inline bool lfs2_pair_sync( const lfs2_block_t paira[2], const lfs2_block_t pairb[2]) { return (paira[0] == pairb[0] && paira[1] == pairb[1]) || (paira[0] == pairb[1] && paira[1] == pairb[0]); } +#endif static inline void lfs2_pair_fromle32(lfs2_block_t pair[2]) { pair[0] = lfs2_fromle32(pair[0]); pair[1] = lfs2_fromle32(pair[1]); } +#ifndef LFS2_READONLY static inline void lfs2_pair_tole32(lfs2_block_t pair[2]) { pair[0] = lfs2_tole32(pair[0]); pair[1] = lfs2_tole32(pair[1]); } +#endif // operations on 32-bit entry tags typedef uint32_t lfs2_tag_t; @@ -365,6 +380,7 @@ static inline bool lfs2_gstate_iszero(const lfs2_gstate_t *a) { return true; } +#ifndef LFS2_READONLY static inline bool lfs2_gstate_hasorphans(const lfs2_gstate_t *a) { return lfs2_tag_size(a->tag); } @@ -376,6 +392,7 @@ static inline uint8_t lfs2_gstate_getorphans(const lfs2_gstate_t *a) { static inline bool lfs2_gstate_hasmove(const lfs2_gstate_t *a) { return lfs2_tag_type1(a->tag); } +#endif static inline bool lfs2_gstate_hasmovehere(const lfs2_gstate_t *a, const lfs2_block_t *pair) { @@ -388,11 +405,13 @@ static inline void lfs2_gstate_fromle32(lfs2_gstate_t *a) { a->pair[1] = lfs2_fromle32(a->pair[1]); } +#ifndef LFS2_READONLY static inline void lfs2_gstate_tole32(lfs2_gstate_t *a) { a->tag = lfs2_tole32(a->tag); a->pair[0] = lfs2_tole32(a->pair[0]); a->pair[1] = lfs2_tole32(a->pair[1]); } +#endif // other endianness operations static void lfs2_ctz_fromle32(struct lfs2_ctz *ctz) { @@ -416,6 +435,7 @@ static inline void lfs2_superblock_fromle32(lfs2_superblock_t *superblock) { superblock->attr_max = lfs2_fromle32(superblock->attr_max); } +#ifndef LFS2_READONLY static inline void lfs2_superblock_tole32(lfs2_superblock_t *superblock) { superblock->version = lfs2_tole32(superblock->version); superblock->block_size = lfs2_tole32(superblock->block_size); @@ -424,9 +444,10 @@ static inline void lfs2_superblock_tole32(lfs2_superblock_t *superblock) { superblock->file_max = lfs2_tole32(superblock->file_max); superblock->attr_max = lfs2_tole32(superblock->attr_max); } +#endif #ifndef LFS2_NO_ASSERT -static inline bool lfs2_mlist_isopen(struct lfs2_mlist *head, +static bool lfs2_mlist_isopen(struct lfs2_mlist *head, struct lfs2_mlist *node) { for (struct lfs2_mlist **p = &head; *p; p = &(*p)->next) { if (*p == (struct lfs2_mlist*)node) { @@ -438,7 +459,7 @@ static inline bool lfs2_mlist_isopen(struct lfs2_mlist *head, } #endif -static inline void lfs2_mlist_remove(lfs2_t *lfs2, struct lfs2_mlist *mlist) { +static void lfs2_mlist_remove(lfs2_t *lfs2, struct lfs2_mlist *mlist) { for (struct lfs2_mlist **p = &lfs2->mlist; *p; p = &(*p)->next) { if (*p == mlist) { *p = (*p)->next; @@ -447,7 +468,7 @@ static inline void lfs2_mlist_remove(lfs2_t *lfs2, struct lfs2_mlist *mlist) { } } -static inline void lfs2_mlist_append(lfs2_t *lfs2, struct lfs2_mlist *mlist) { +static void lfs2_mlist_append(lfs2_t *lfs2, struct lfs2_mlist *mlist) { mlist->next = lfs2->mlist; lfs2->mlist = mlist; } @@ -460,22 +481,22 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, static int lfs2_dir_compact(lfs2_t *lfs2, lfs2_mdir_t *dir, const struct lfs2_mattr *attrs, int attrcount, lfs2_mdir_t *source, uint16_t begin, uint16_t end); - +static lfs2_ssize_t lfs2_file_flushedwrite(lfs2_t *lfs2, lfs2_file_t *file, + const void *buffer, lfs2_size_t size); static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, const void *buffer, lfs2_size_t size); static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file); static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file); static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file); -static void lfs2_fs_preporphans(lfs2_t *lfs2, int8_t orphans); +static int lfs2_fs_deorphan(lfs2_t *lfs2, bool powerloss); +static int lfs2_fs_preporphans(lfs2_t *lfs2, int8_t orphans); static void lfs2_fs_prepmove(lfs2_t *lfs2, uint16_t id, const lfs2_block_t pair[2]); static int lfs2_fs_pred(lfs2_t *lfs2, const lfs2_block_t dir[2], lfs2_mdir_t *pdir); static lfs2_stag_t lfs2_fs_parent(lfs2_t *lfs2, const lfs2_block_t dir[2], lfs2_mdir_t *parent); -static int lfs2_fs_relocate(lfs2_t *lfs2, - const lfs2_block_t oldpair[2], lfs2_block_t newpair[2]); static int lfs2_fs_forceconsistency(lfs2_t *lfs2); #endif @@ -486,6 +507,8 @@ static int lfs21_traverse(lfs2_t *lfs2, static int lfs2_dir_rawrewind(lfs2_t *lfs2, lfs2_dir_t *dir); +static lfs2_ssize_t lfs2_file_flushedread(lfs2_t *lfs2, lfs2_file_t *file, + void *buffer, lfs2_size_t size); static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, void *buffer, lfs2_size_t size); static int lfs2_file_rawclose(lfs2_t *lfs2, lfs2_file_t *file); @@ -726,6 +749,7 @@ static int lfs2_dir_traverse_filter(void *p, (LFS2_MKTAG(0x7ff, 0x3ff, 0) & tag) == ( LFS2_MKTAG(LFS2_TYPE_DELETE, 0, 0) | (LFS2_MKTAG(0, 0x3ff, 0) & *filtertag))) { + *filtertag = LFS2_MKTAG(LFS2_FROM_NOOP, 0, 0); return true; } @@ -740,98 +764,227 @@ static int lfs2_dir_traverse_filter(void *p, #endif #ifndef LFS2_READONLY +// maximum recursive depth of lfs2_dir_traverse, the deepest call: +// +// traverse with commit +// '-> traverse with move +// '-> traverse with filter +// +#define LFS2_DIR_TRAVERSE_DEPTH 3 + +struct lfs2_dir_traverse { + const lfs2_mdir_t *dir; + lfs2_off_t off; + lfs2_tag_t ptag; + const struct lfs2_mattr *attrs; + int attrcount; + + lfs2_tag_t tmask; + lfs2_tag_t ttag; + uint16_t begin; + uint16_t end; + int16_t diff; + + int (*cb)(void *data, lfs2_tag_t tag, const void *buffer); + void *data; + + lfs2_tag_t tag; + const void *buffer; + struct lfs2_diskoff disk; +}; + static int lfs2_dir_traverse(lfs2_t *lfs2, const lfs2_mdir_t *dir, lfs2_off_t off, lfs2_tag_t ptag, const struct lfs2_mattr *attrs, int attrcount, lfs2_tag_t tmask, lfs2_tag_t ttag, uint16_t begin, uint16_t end, int16_t diff, int (*cb)(void *data, lfs2_tag_t tag, const void *buffer), void *data) { + // This function in inherently recursive, but bounded. To allow tool-based + // analysis without unnecessary code-cost we use an explicit stack + struct lfs2_dir_traverse stack[LFS2_DIR_TRAVERSE_DEPTH-1]; + unsigned sp = 0; + int res; + // iterate over directory and attrs + lfs2_tag_t tag; + const void *buffer; + struct lfs2_diskoff disk; while (true) { - lfs2_tag_t tag; - const void *buffer; - struct lfs2_diskoff disk; - if (off+lfs2_tag_dsize(ptag) < dir->off) { - off += lfs2_tag_dsize(ptag); - int err = lfs2_bd_read(lfs2, - NULL, &lfs2->rcache, sizeof(tag), - dir->pair[0], off, &tag, sizeof(tag)); - if (err) { - return err; - } - - tag = (lfs2_frombe32(tag) ^ ptag) | 0x80000000; - disk.block = dir->pair[0]; - disk.off = off+sizeof(lfs2_tag_t); - buffer = &disk; - ptag = tag; - } else if (attrcount > 0) { - tag = attrs[0].tag; - buffer = attrs[0].buffer; - attrs += 1; - attrcount -= 1; - } else { - return 0; - } - - lfs2_tag_t mask = LFS2_MKTAG(0x7ff, 0, 0); - if ((mask & tmask & tag) != (mask & tmask & ttag)) { - continue; - } + { + if (off+lfs2_tag_dsize(ptag) < dir->off) { + off += lfs2_tag_dsize(ptag); + int err = lfs2_bd_read(lfs2, + NULL, &lfs2->rcache, sizeof(tag), + dir->pair[0], off, &tag, sizeof(tag)); + if (err) { + return err; + } - // do we need to filter? inlining the filtering logic here allows - // for some minor optimizations - if (lfs2_tag_id(tmask) != 0) { - // scan for duplicates and update tag based on creates/deletes - int filter = lfs2_dir_traverse(lfs2, - dir, off, ptag, attrs, attrcount, - 0, 0, 0, 0, 0, - lfs2_dir_traverse_filter, &tag); - if (filter < 0) { - return filter; + tag = (lfs2_frombe32(tag) ^ ptag) | 0x80000000; + disk.block = dir->pair[0]; + disk.off = off+sizeof(lfs2_tag_t); + buffer = &disk; + ptag = tag; + } else if (attrcount > 0) { + tag = attrs[0].tag; + buffer = attrs[0].buffer; + attrs += 1; + attrcount -= 1; + } else { + // finished traversal, pop from stack? + res = 0; + break; } - if (filter) { + // do we need to filter? + lfs2_tag_t mask = LFS2_MKTAG(0x7ff, 0, 0); + if ((mask & tmask & tag) != (mask & tmask & ttag)) { continue; } - // in filter range? - if (!(lfs2_tag_id(tag) >= begin && lfs2_tag_id(tag) < end)) { + if (lfs2_tag_id(tmask) != 0) { + LFS2_ASSERT(sp < LFS2_DIR_TRAVERSE_DEPTH); + // recurse, scan for duplicates, and update tag based on + // creates/deletes + stack[sp] = (struct lfs2_dir_traverse){ + .dir = dir, + .off = off, + .ptag = ptag, + .attrs = attrs, + .attrcount = attrcount, + .tmask = tmask, + .ttag = ttag, + .begin = begin, + .end = end, + .diff = diff, + .cb = cb, + .data = data, + .tag = tag, + .buffer = buffer, + .disk = disk, + }; + sp += 1; + + tmask = 0; + ttag = 0; + begin = 0; + end = 0; + diff = 0; + cb = lfs2_dir_traverse_filter; + data = &stack[sp-1].tag; continue; } } +popped: + // in filter range? + if (lfs2_tag_id(tmask) != 0 && + !(lfs2_tag_id(tag) >= begin && lfs2_tag_id(tag) < end)) { + continue; + } + // handle special cases for mcu-side operations if (lfs2_tag_type3(tag) == LFS2_FROM_NOOP) { // do nothing } else if (lfs2_tag_type3(tag) == LFS2_FROM_MOVE) { + // Without this condition, lfs2_dir_traverse can exhibit an + // extremely expensive O(n^3) of nested loops when renaming. + // This happens because lfs2_dir_traverse tries to filter tags by + // the tags in the source directory, triggering a second + // lfs2_dir_traverse with its own filter operation. + // + // traverse with commit + // '-> traverse with filter + // '-> traverse with move + // '-> traverse with filter + // + // However we don't actually care about filtering the second set of + // tags, since duplicate tags have no effect when filtering. + // + // This check skips this unnecessary recursive filtering explicitly, + // reducing this runtime from O(n^3) to O(n^2). + if (cb == lfs2_dir_traverse_filter) { + continue; + } + + // recurse into move + stack[sp] = (struct lfs2_dir_traverse){ + .dir = dir, + .off = off, + .ptag = ptag, + .attrs = attrs, + .attrcount = attrcount, + .tmask = tmask, + .ttag = ttag, + .begin = begin, + .end = end, + .diff = diff, + .cb = cb, + .data = data, + .tag = LFS2_MKTAG(LFS2_FROM_NOOP, 0, 0), + }; + sp += 1; + uint16_t fromid = lfs2_tag_size(tag); uint16_t toid = lfs2_tag_id(tag); - int err = lfs2_dir_traverse(lfs2, - buffer, 0, 0xffffffff, NULL, 0, - LFS2_MKTAG(0x600, 0x3ff, 0), - LFS2_MKTAG(LFS2_TYPE_STRUCT, 0, 0), - fromid, fromid+1, toid-fromid+diff, - cb, data); - if (err) { - return err; - } + dir = buffer; + off = 0; + ptag = 0xffffffff; + attrs = NULL; + attrcount = 0; + tmask = LFS2_MKTAG(0x600, 0x3ff, 0); + ttag = LFS2_MKTAG(LFS2_TYPE_STRUCT, 0, 0); + begin = fromid; + end = fromid+1; + diff = toid-fromid+diff; } else if (lfs2_tag_type3(tag) == LFS2_FROM_USERATTRS) { for (unsigned i = 0; i < lfs2_tag_size(tag); i++) { const struct lfs2_attr *a = buffer; - int err = cb(data, LFS2_MKTAG(LFS2_TYPE_USERATTR + a[i].type, + res = cb(data, LFS2_MKTAG(LFS2_TYPE_USERATTR + a[i].type, lfs2_tag_id(tag) + diff, a[i].size), a[i].buffer); - if (err) { - return err; + if (res < 0) { + return res; + } + + if (res) { + break; } } } else { - int err = cb(data, tag + LFS2_MKTAG(0, diff, 0), buffer); - if (err) { - return err; + res = cb(data, tag + LFS2_MKTAG(0, diff, 0), buffer); + if (res < 0) { + return res; + } + + if (res) { + break; } } } + + if (sp > 0) { + // pop from the stack and return, fortunately all pops share + // a destination + dir = stack[sp-1].dir; + off = stack[sp-1].off; + ptag = stack[sp-1].ptag; + attrs = stack[sp-1].attrs; + attrcount = stack[sp-1].attrcount; + tmask = stack[sp-1].tmask; + ttag = stack[sp-1].ttag; + begin = stack[sp-1].begin; + end = stack[sp-1].end; + diff = stack[sp-1].diff; + cb = stack[sp-1].cb; + data = stack[sp-1].data; + tag = stack[sp-1].tag; + buffer = stack[sp-1].buffer; + disk = stack[sp-1].disk; + sp -= 1; + goto popped; + } else { + return res; + } } #endif @@ -1449,7 +1602,7 @@ static int lfs2_dir_alloc(lfs2_t *lfs2, lfs2_mdir_t *dir) { } } - // zero for reproducability in case initial block is unreadable + // zero for reproducibility in case initial block is unreadable dir->rev = 0; // rather than clobbering one of the blocks we just pretend @@ -1508,8 +1661,7 @@ static int lfs2_dir_drop(lfs2_t *lfs2, lfs2_mdir_t *dir, lfs2_mdir_t *tail) { static int lfs2_dir_split(lfs2_t *lfs2, lfs2_mdir_t *dir, const struct lfs2_mattr *attrs, int attrcount, lfs2_mdir_t *source, uint16_t split, uint16_t end) { - // create tail directory - lfs2_alloc_ack(lfs2); + // create tail metadata pair lfs2_mdir_t tail; int err = lfs2_dir_alloc(lfs2, &tail); if (err) { @@ -1520,9 +1672,10 @@ static int lfs2_dir_split(lfs2_t *lfs2, tail.tail[0] = dir->tail[0]; tail.tail[1] = dir->tail[1]; - err = lfs2_dir_compact(lfs2, &tail, attrs, attrcount, source, split, end); - if (err) { - return err; + // note we don't care about LFS2_OK_RELOCATED + int res = lfs2_dir_compact(lfs2, &tail, attrs, attrcount, source, split, end); + if (res < 0) { + return res; } dir->tail[0] = tail.pair[0]; @@ -1563,106 +1716,45 @@ static int lfs2_dir_commit_commit(void *p, lfs2_tag_t tag, const void *buffer) { } #endif +#ifndef LFS2_READONLY +static bool lfs2_dir_needsrelocation(lfs2_t *lfs2, lfs2_mdir_t *dir) { + // If our revision count == n * block_cycles, we should force a relocation, + // this is how littlefs wear-levels at the metadata-pair level. Note that we + // actually use (block_cycles+1)|1, this is to avoid two corner cases: + // 1. block_cycles = 1, which would prevent relocations from terminating + // 2. block_cycles = 2n, which, due to aliasing, would only ever relocate + // one metadata block in the pair, effectively making this useless + return (lfs2->cfg->block_cycles > 0 + && ((dir->rev + 1) % ((lfs2->cfg->block_cycles+1)|1) == 0)); +} +#endif + #ifndef LFS2_READONLY static int lfs2_dir_compact(lfs2_t *lfs2, lfs2_mdir_t *dir, const struct lfs2_mattr *attrs, int attrcount, lfs2_mdir_t *source, uint16_t begin, uint16_t end) { // save some state in case block is bad - const lfs2_block_t oldpair[2] = {dir->pair[0], dir->pair[1]}; bool relocated = false; - bool tired = false; - - // should we split? - while (end - begin > 1) { - // find size - lfs2_size_t size = 0; - int err = lfs2_dir_traverse(lfs2, - source, 0, 0xffffffff, attrs, attrcount, - LFS2_MKTAG(0x400, 0x3ff, 0), - LFS2_MKTAG(LFS2_TYPE_NAME, 0, 0), - begin, end, -begin, - lfs2_dir_commit_size, &size); - if (err) { - return err; - } - - // space is complicated, we need room for tail, crc, gstate, - // cleanup delete, and we cap at half a block to give room - // for metadata updates. - if (end - begin < 0xff && - size <= lfs2_min(lfs2->cfg->block_size - 36, - lfs2_alignup(lfs2->cfg->block_size/2, - lfs2->cfg->prog_size))) { - break; - } - - // can't fit, need to split, we should really be finding the - // largest size that fits with a small binary search, but right now - // it's not worth the code size - uint16_t split = (end - begin) / 2; - err = lfs2_dir_split(lfs2, dir, attrs, attrcount, - source, begin+split, end); - if (err) { - // if we fail to split, we may be able to overcompact, unless - // we're too big for even the full block, in which case our - // only option is to error - if (err == LFS2_ERR_NOSPC && size <= lfs2->cfg->block_size - 36) { - break; - } - return err; - } - - end = begin + split; - } + bool tired = lfs2_dir_needsrelocation(lfs2, dir); // increment revision count dir->rev += 1; - // If our revision count == n * block_cycles, we should force a relocation, - // this is how littlefs wear-levels at the metadata-pair level. Note that we - // actually use (block_cycles+1)|1, this is to avoid two corner cases: - // 1. block_cycles = 1, which would prevent relocations from terminating - // 2. block_cycles = 2n, which, due to aliasing, would only ever relocate - // one metadata block in the pair, effectively making this useless - if (lfs2->cfg->block_cycles > 0 && - (dir->rev % ((lfs2->cfg->block_cycles+1)|1) == 0)) { - if (lfs2_pair_cmp(dir->pair, (const lfs2_block_t[2]){0, 1}) == 0) { - // oh no! we're writing too much to the superblock, - // should we expand? - lfs2_ssize_t res = lfs2_fs_rawsize(lfs2); - if (res < 0) { - return res; - } - // do we have extra space? littlefs can't reclaim this space - // by itself, so expand cautiously - if ((lfs2_size_t)res < lfs2->cfg->block_count/2) { - LFS2_DEBUG("Expanding superblock at rev %"PRIu32, dir->rev); - int err = lfs2_dir_split(lfs2, dir, attrs, attrcount, - source, begin, end); - if (err && err != LFS2_ERR_NOSPC) { - return err; - } - - // welp, we tried, if we ran out of space there's not much - // we can do, we'll error later if we've become frozen - if (!err) { - end = begin; - } - } + // do not proactively relocate blocks during migrations, this + // can cause a number of failure states such: clobbering the + // v1 superblock if we relocate root, and invalidating directory + // pointers if we relocate the head of a directory. On top of + // this, relocations increase the overall complexity of + // lfs2_migration, which is already a delicate operation. #ifdef LFS2_MIGRATE - } else if (lfs2->lfs21) { - // do not proactively relocate blocks during migrations, this - // can cause a number of failure states such: clobbering the - // v1 superblock if we relocate root, and invalidating directory - // pointers if we relocate the head of a directory. On top of - // this, relocations increase the overall complexity of - // lfs2_migration, which is already a delicate operation. + if (lfs2->lfs21) { + tired = false; + } #endif - } else { - // we're writing too much, time to relocate - tired = true; - goto relocate; - } + + if (tired && lfs2_pair_cmp(dir->pair, (const lfs2_block_t[2]){0, 1}) != 0) { + // we're writing too much, time to relocate + goto relocate; } // begin loop to commit compaction to blocks until a compact sticks @@ -1676,7 +1768,8 @@ static int lfs2_dir_compact(lfs2_t *lfs2, .crc = 0xffffffff, .begin = 0, - .end = lfs2->cfg->block_size - 8, + .end = (lfs2->cfg->metadata_max ? + lfs2->cfg->metadata_max : lfs2->cfg->block_size) - 8, }; // erase block to write to @@ -1805,44 +1898,114 @@ static int lfs2_dir_compact(lfs2_t *lfs2, continue; } - if (relocated) { - // update references if we relocated - LFS2_DEBUG("Relocating {0x%"PRIx32", 0x%"PRIx32"} " - "-> {0x%"PRIx32", 0x%"PRIx32"}", - oldpair[0], oldpair[1], dir->pair[0], dir->pair[1]); - int err = lfs2_fs_relocate(lfs2, oldpair, dir->pair); - if (err) { - return err; - } - } - - return 0; + return relocated ? LFS2_OK_RELOCATED : 0; } #endif #ifndef LFS2_READONLY -static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, - const struct lfs2_mattr *attrs, int attrcount) { - // check for any inline files that aren't RAM backed and - // forcefully evict them, needed for filesystem consistency - for (lfs2_file_t *f = (lfs2_file_t*)lfs2->mlist; f; f = f->next) { - if (dir != &f->m && lfs2_pair_cmp(f->m.pair, dir->pair) == 0 && - f->type == LFS2_TYPE_REG && (f->flags & LFS2_F_INLINE) && - f->ctz.size > lfs2->cfg->cache_size) { - int err = lfs2_file_outline(lfs2, f); +static int lfs2_dir_splittingcompact(lfs2_t *lfs2, lfs2_mdir_t *dir, + const struct lfs2_mattr *attrs, int attrcount, + lfs2_mdir_t *source, uint16_t begin, uint16_t end) { + while (true) { + // find size of first split, we do this by halving the split until + // the metadata is guaranteed to fit + // + // Note that this isn't a true binary search, we never increase the + // split size. This may result in poorly distributed metadata but isn't + // worth the extra code size or performance hit to fix. + lfs2_size_t split = begin; + while (end - split > 1) { + lfs2_size_t size = 0; + int err = lfs2_dir_traverse(lfs2, + source, 0, 0xffffffff, attrs, attrcount, + LFS2_MKTAG(0x400, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_NAME, 0, 0), + split, end, -split, + lfs2_dir_commit_size, &size); if (err) { return err; } - err = lfs2_file_flush(lfs2, f); - if (err) { + // space is complicated, we need room for tail, crc, gstate, + // cleanup delete, and we cap at half a block to give room + // for metadata updates. + if (end - split < 0xff + && size <= lfs2_min(lfs2->cfg->block_size - 36, + lfs2_alignup( + (lfs2->cfg->metadata_max + ? lfs2->cfg->metadata_max + : lfs2->cfg->block_size)/2, + lfs2->cfg->prog_size))) { + break; + } + + split = split + ((end - split) / 2); + } + + if (split == begin) { + // no split needed + break; + } + + // split into two metadata pairs and continue + int err = lfs2_dir_split(lfs2, dir, attrs, attrcount, + source, split, end); + if (err && err != LFS2_ERR_NOSPC) { + return err; + } + + if (err) { + // we can't allocate a new block, try to compact with degraded + // performance + LFS2_WARN("Unable to split {0x%"PRIx32", 0x%"PRIx32"}", + dir->pair[0], dir->pair[1]); + break; + } else { + end = split; + } + } + + if (lfs2_dir_needsrelocation(lfs2, dir) + && lfs2_pair_cmp(dir->pair, (const lfs2_block_t[2]){0, 1}) == 0) { + // oh no! we're writing too much to the superblock, + // should we expand? + lfs2_ssize_t size = lfs2_fs_rawsize(lfs2); + if (size < 0) { + return size; + } + + // do we have extra space? littlefs can't reclaim this space + // by itself, so expand cautiously + if ((lfs2_size_t)size < lfs2->cfg->block_count/2) { + LFS2_DEBUG("Expanding superblock at rev %"PRIu32, dir->rev); + int err = lfs2_dir_split(lfs2, dir, attrs, attrcount, + source, begin, end); + if (err && err != LFS2_ERR_NOSPC) { return err; } + + if (err) { + // welp, we tried, if we ran out of space there's not much + // we can do, we'll error later if we've become frozen + LFS2_WARN("Unable to expand superblock"); + } else { + end = begin; + } } } + return lfs2_dir_compact(lfs2, dir, attrs, attrcount, source, begin, end); +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_relocatingcommit(lfs2_t *lfs2, lfs2_mdir_t *dir, + const lfs2_block_t pair[2], + const struct lfs2_mattr *attrs, int attrcount, + lfs2_mdir_t *pdir) { + int state = 0; + // calculate changes to the directory - lfs2_mdir_t olddir = *dir; bool hasdelete = false; for (int i = 0; i < attrcount; i++) { if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_CREATE) { @@ -1861,23 +2024,19 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, // should we actually drop the directory block? if (hasdelete && dir->count == 0) { - lfs2_mdir_t pdir; - int err = lfs2_fs_pred(lfs2, dir->pair, &pdir); + LFS2_ASSERT(pdir); + int err = lfs2_fs_pred(lfs2, dir->pair, pdir); if (err && err != LFS2_ERR_NOENT) { - *dir = olddir; return err; } - if (err != LFS2_ERR_NOENT && pdir.split) { - err = lfs2_dir_drop(lfs2, &pdir, dir); - if (err) { - *dir = olddir; - return err; - } + if (err != LFS2_ERR_NOENT && pdir->split) { + state = LFS2_OK_DROPPED; + goto fixmlist; } } - if (dir->erased || dir->count >= 0xff) { + if (dir->erased) { // try to commit struct lfs2_commit commit = { .block = dir->pair[0], @@ -1886,7 +2045,8 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, .crc = 0xffffffff, .begin = dir->off, - .end = lfs2->cfg->block_size - 8, + .end = (lfs2->cfg->metadata_max ? + lfs2->cfg->metadata_max : lfs2->cfg->block_size) - 8, }; // traverse attrs that need to be written out @@ -1901,7 +2061,6 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, if (err == LFS2_ERR_NOSPC || err == LFS2_ERR_CORRUPT) { goto compact; } - *dir = olddir; return err; } @@ -1914,7 +2073,6 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, if (!lfs2_gstate_iszero(&delta)) { err = lfs2_dir_getgstate(lfs2, dir, &delta); if (err) { - *dir = olddir; return err; } @@ -1926,7 +2084,6 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, if (err == LFS2_ERR_NOSPC || err == LFS2_ERR_CORRUPT) { goto compact; } - *dir = olddir; return err; } } @@ -1937,7 +2094,6 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, if (err == LFS2_ERR_NOSPC || err == LFS2_ERR_CORRUPT) { goto compact; } - *dir = olddir; return err; } @@ -1948,19 +2104,23 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, // and update gstate lfs2->gdisk = lfs2->gstate; lfs2->gdelta = (lfs2_gstate_t){0}; - } else { + + goto fixmlist; + } + compact: - // fall back to compaction - lfs2_cache_drop(lfs2, &lfs2->pcache); + // fall back to compaction + lfs2_cache_drop(lfs2, &lfs2->pcache); - int err = lfs2_dir_compact(lfs2, dir, attrs, attrcount, - dir, 0, dir->count); - if (err) { - *dir = olddir; - return err; - } + state = lfs2_dir_splittingcompact(lfs2, dir, attrs, attrcount, + dir, 0, dir->count); + if (state < 0) { + return state; } + goto fixmlist; + +fixmlist:; // this complicated bit of logic is for fixing up any active // metadata-pairs that we may have affected // @@ -1968,33 +2128,32 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, // lfs2_dir_commit could also be in this list, and even then // we need to copy the pair so they don't get clobbered if we refetch // our mdir. + lfs2_block_t oldpair[2] = {pair[0], pair[1]}; for (struct lfs2_mlist *d = lfs2->mlist; d; d = d->next) { - if (&d->m != dir && lfs2_pair_cmp(d->m.pair, olddir.pair) == 0) { + if (lfs2_pair_cmp(d->m.pair, oldpair) == 0) { d->m = *dir; - for (int i = 0; i < attrcount; i++) { - if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && - d->id == lfs2_tag_id(attrs[i].tag)) { - d->m.pair[0] = LFS2_BLOCK_NULL; - d->m.pair[1] = LFS2_BLOCK_NULL; - } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && - d->id > lfs2_tag_id(attrs[i].tag)) { - d->id -= 1; - if (d->type == LFS2_TYPE_DIR) { - ((lfs2_dir_t*)d)->pos -= 1; - } - } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_CREATE && - d->id >= lfs2_tag_id(attrs[i].tag)) { - d->id += 1; - if (d->type == LFS2_TYPE_DIR) { - ((lfs2_dir_t*)d)->pos += 1; + if (d->m.pair != pair) { + for (int i = 0; i < attrcount; i++) { + if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && + d->id == lfs2_tag_id(attrs[i].tag)) { + d->m.pair[0] = LFS2_BLOCK_NULL; + d->m.pair[1] = LFS2_BLOCK_NULL; + } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && + d->id > lfs2_tag_id(attrs[i].tag)) { + d->id -= 1; + if (d->type == LFS2_TYPE_DIR) { + ((lfs2_dir_t*)d)->pos -= 1; + } + } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_CREATE && + d->id >= lfs2_tag_id(attrs[i].tag)) { + d->id += 1; + if (d->type == LFS2_TYPE_DIR) { + ((lfs2_dir_t*)d)->pos += 1; + } } } } - } - } - for (struct lfs2_mlist *d = lfs2->mlist; d; d = d->next) { - if (lfs2_pair_cmp(d->m.pair, olddir.pair) == 0) { while (d->id >= d->m.count && d->m.split) { // we split and id is on tail now d->id -= d->m.count; @@ -2006,6 +2165,221 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, } } + return state; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_orphaningcommit(lfs2_t *lfs2, lfs2_mdir_t *dir, + const struct lfs2_mattr *attrs, int attrcount) { + // check for any inline files that aren't RAM backed and + // forcefully evict them, needed for filesystem consistency + for (lfs2_file_t *f = (lfs2_file_t*)lfs2->mlist; f; f = f->next) { + if (dir != &f->m && lfs2_pair_cmp(f->m.pair, dir->pair) == 0 && + f->type == LFS2_TYPE_REG && (f->flags & LFS2_F_INLINE) && + f->ctz.size > lfs2->cfg->cache_size) { + int err = lfs2_file_outline(lfs2, f); + if (err) { + return err; + } + + err = lfs2_file_flush(lfs2, f); + if (err) { + return err; + } + } + } + + lfs2_block_t lpair[2] = {dir->pair[0], dir->pair[1]}; + lfs2_mdir_t ldir = *dir; + lfs2_mdir_t pdir; + int state = lfs2_dir_relocatingcommit(lfs2, &ldir, dir->pair, + attrs, attrcount, &pdir); + if (state < 0) { + return state; + } + + // update if we're not in mlist, note we may have already been + // updated if we are in mlist + if (lfs2_pair_cmp(dir->pair, lpair) == 0) { + *dir = ldir; + } + + // commit was successful, but may require other changes in the + // filesystem, these would normally be tail recursive, but we have + // flattened them here avoid unbounded stack usage + + // need to drop? + if (state == LFS2_OK_DROPPED) { + // steal state + int err = lfs2_dir_getgstate(lfs2, dir, &lfs2->gdelta); + if (err) { + return err; + } + + // steal tail, note that this can't create a recursive drop + lpair[0] = pdir.pair[0]; + lpair[1] = pdir.pair[1]; + lfs2_pair_tole32(dir->tail); + state = lfs2_dir_relocatingcommit(lfs2, &pdir, lpair, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_TAIL + dir->split, 0x3ff, 8), + dir->tail}), + NULL); + lfs2_pair_fromle32(dir->tail); + if (state < 0) { + return state; + } + + ldir = pdir; + } + + // need to relocate? + bool orphans = false; + while (state == LFS2_OK_RELOCATED) { + LFS2_DEBUG("Relocating {0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + lpair[0], lpair[1], ldir.pair[0], ldir.pair[1]); + state = 0; + + // update internal root + if (lfs2_pair_cmp(lpair, lfs2->root) == 0) { + lfs2->root[0] = ldir.pair[0]; + lfs2->root[1] = ldir.pair[1]; + } + + // update internally tracked dirs + for (struct lfs2_mlist *d = lfs2->mlist; d; d = d->next) { + if (lfs2_pair_cmp(lpair, d->m.pair) == 0) { + d->m.pair[0] = ldir.pair[0]; + d->m.pair[1] = ldir.pair[1]; + } + + if (d->type == LFS2_TYPE_DIR && + lfs2_pair_cmp(lpair, ((lfs2_dir_t*)d)->head) == 0) { + ((lfs2_dir_t*)d)->head[0] = ldir.pair[0]; + ((lfs2_dir_t*)d)->head[1] = ldir.pair[1]; + } + } + + // find parent + lfs2_stag_t tag = lfs2_fs_parent(lfs2, lpair, &pdir); + if (tag < 0 && tag != LFS2_ERR_NOENT) { + return tag; + } + + bool hasparent = (tag != LFS2_ERR_NOENT); + if (tag != LFS2_ERR_NOENT) { + // note that if we have a parent, we must have a pred, so this will + // always create an orphan + int err = lfs2_fs_preporphans(lfs2, +1); + if (err) { + return err; + } + + // fix pending move in this pair? this looks like an optimization but + // is in fact _required_ since relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs2_gstate_hasmovehere(&lfs2->gstate, pdir.pair)) { + moveid = lfs2_tag_id(lfs2->gstate.tag); + LFS2_DEBUG("Fixing move while relocating " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + pdir.pair[0], pdir.pair[1], moveid); + lfs2_fs_prepmove(lfs2, 0x3ff, NULL); + if (moveid < lfs2_tag_id(tag)) { + tag -= LFS2_MKTAG(0, 1, 0); + } + } + + lfs2_block_t ppair[2] = {pdir.pair[0], pdir.pair[1]}; + lfs2_pair_tole32(ldir.pair); + state = lfs2_dir_relocatingcommit(lfs2, &pdir, ppair, LFS2_MKATTRS( + {LFS2_MKTAG_IF(moveid != 0x3ff, + LFS2_TYPE_DELETE, moveid, 0), NULL}, + {tag, ldir.pair}), + NULL); + lfs2_pair_fromle32(ldir.pair); + if (state < 0) { + return state; + } + + if (state == LFS2_OK_RELOCATED) { + lpair[0] = ppair[0]; + lpair[1] = ppair[1]; + ldir = pdir; + orphans = true; + continue; + } + } + + // find pred + int err = lfs2_fs_pred(lfs2, lpair, &pdir); + if (err && err != LFS2_ERR_NOENT) { + return err; + } + LFS2_ASSERT(!(hasparent && err == LFS2_ERR_NOENT)); + + // if we can't find dir, it must be new + if (err != LFS2_ERR_NOENT) { + if (lfs2_gstate_hasorphans(&lfs2->gstate)) { + // next step, clean up orphans + err = lfs2_fs_preporphans(lfs2, -hasparent); + if (err) { + return err; + } + } + + // fix pending move in this pair? this looks like an optimization + // but is in fact _required_ since relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs2_gstate_hasmovehere(&lfs2->gstate, pdir.pair)) { + moveid = lfs2_tag_id(lfs2->gstate.tag); + LFS2_DEBUG("Fixing move while relocating " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + pdir.pair[0], pdir.pair[1], moveid); + lfs2_fs_prepmove(lfs2, 0x3ff, NULL); + } + + // replace bad pair, either we clean up desync, or no desync occured + lpair[0] = pdir.pair[0]; + lpair[1] = pdir.pair[1]; + lfs2_pair_tole32(ldir.pair); + state = lfs2_dir_relocatingcommit(lfs2, &pdir, lpair, LFS2_MKATTRS( + {LFS2_MKTAG_IF(moveid != 0x3ff, + LFS2_TYPE_DELETE, moveid, 0), NULL}, + {LFS2_MKTAG(LFS2_TYPE_TAIL + pdir.split, 0x3ff, 8), + ldir.pair}), + NULL); + lfs2_pair_fromle32(ldir.pair); + if (state < 0) { + return state; + } + + ldir = pdir; + } + } + + return orphans ? LFS2_OK_ORPHANED : 0; +} +#endif + +#ifndef LFS2_READONLY +static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, + const struct lfs2_mattr *attrs, int attrcount) { + int orphans = lfs2_dir_orphaningcommit(lfs2, dir, attrs, attrcount); + if (orphans < 0) { + return orphans; + } + + if (orphans) { + // make sure we've removed all orphans, this is a noop if there + // are none, but if we had nested blocks failures we may have + // created some + int err = lfs2_fs_deorphan(lfs2, false); + if (err) { + return err; + } + } + return 0; } #endif @@ -2060,10 +2434,13 @@ static int lfs2_rawmkdir(lfs2_t *lfs2, const char *path) { return err; } - // current block end of list? + // current block not end of list? if (cwd.m.split) { // update tails, this creates a desync - lfs2_fs_preporphans(lfs2, +1); + err = lfs2_fs_preporphans(lfs2, +1); + if (err) { + return err; + } // it's possible our predecessor has to be relocated, and if // our parent is our predecessor's predecessor, this could have @@ -2083,7 +2460,10 @@ static int lfs2_rawmkdir(lfs2_t *lfs2, const char *path) { } lfs2->mlist = cwd.next; - lfs2_fs_preporphans(lfs2, -1); + err = lfs2_fs_preporphans(lfs2, -1); + if (err) { + return err; + } } // now insert into our parent block @@ -2504,8 +2884,11 @@ static int lfs2_file_rawopencfg(lfs2_t *lfs2, lfs2_file_t *file, {LFS2_MKTAG(LFS2_TYPE_CREATE, file->id, 0), NULL}, {LFS2_MKTAG(LFS2_TYPE_REG, file->id, nlen), path}, {LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, file->id, 0), NULL})); + + // it may happen that the file name doesn't fit in the metadata blocks, e.g., a 256 byte file name will + // not fit in a 128 byte block. + err = (err == LFS2_ERR_NOSPC) ? LFS2_ERR_NAMETOOLONG : err; if (err) { - err = LFS2_ERR_NAMETOOLONG; goto cleanup; } @@ -2610,12 +2993,14 @@ static int lfs2_file_rawopencfg(lfs2_t *lfs2, lfs2_file_t *file, return err; } +#ifndef LFS2_NO_MALLOC static int lfs2_file_rawopen(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags) { static const struct lfs2_file_config defaults = {0}; int err = lfs2_file_rawopencfg(lfs2, file, path, flags, &defaults); return err; } +#endif static int lfs2_file_rawclose(lfs2_t *lfs2, lfs2_file_t *file) { #ifndef LFS2_READONLY @@ -2721,7 +3106,6 @@ static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file) { } #endif -#ifndef LFS2_READONLY static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { if (file->flags & LFS2_F_READING) { if (!(file->flags & LFS2_F_INLINE)) { @@ -2730,6 +3114,7 @@ static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { file->flags &= ~LFS2_F_READING; } +#ifndef LFS2_READONLY if (file->flags & LFS2_F_WRITING) { lfs2_off_t pos = file->pos; @@ -2748,12 +3133,12 @@ static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { // copy over a byte at a time, leave it up to caching // to make this efficient uint8_t data; - lfs2_ssize_t res = lfs2_file_rawread(lfs2, &orig, &data, 1); + lfs2_ssize_t res = lfs2_file_flushedread(lfs2, &orig, &data, 1); if (res < 0) { return res; } - res = lfs2_file_rawwrite(lfs2, file, &data, 1); + res = lfs2_file_flushedwrite(lfs2, file, &data, 1); if (res < 0) { return res; } @@ -2796,10 +3181,10 @@ static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { file->pos = pos; } +#endif return 0; } -#endif #ifndef LFS2_READONLY static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file) { @@ -2854,23 +3239,11 @@ static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file) { } #endif -static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, +static lfs2_ssize_t lfs2_file_flushedread(lfs2_t *lfs2, lfs2_file_t *file, void *buffer, lfs2_size_t size) { - LFS2_ASSERT((file->flags & LFS2_O_RDONLY) == LFS2_O_RDONLY); - uint8_t *data = buffer; lfs2_size_t nsize = size; -#ifndef LFS2_READONLY - if (file->flags & LFS2_F_WRITING) { - // flush out any writes - int err = lfs2_file_flush(lfs2, file); - if (err) { - return err; - } - } -#endif - if (file->pos >= file->ctz.size) { // eof if past end return 0; @@ -2927,48 +3300,36 @@ static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, return size; } -#ifndef LFS2_READONLY -static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, - const void *buffer, lfs2_size_t size) { - LFS2_ASSERT((file->flags & LFS2_O_WRONLY) == LFS2_O_WRONLY); - - const uint8_t *data = buffer; - lfs2_size_t nsize = size; +static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, + void *buffer, lfs2_size_t size) { + LFS2_ASSERT((file->flags & LFS2_O_RDONLY) == LFS2_O_RDONLY); - if (file->flags & LFS2_F_READING) { - // drop any reads +#ifndef LFS2_READONLY + if (file->flags & LFS2_F_WRITING) { + // flush out any writes int err = lfs2_file_flush(lfs2, file); if (err) { return err; } } +#endif - if ((file->flags & LFS2_O_APPEND) && file->pos < file->ctz.size) { - file->pos = file->ctz.size; - } - - if (file->pos + size > lfs2->file_max) { - // Larger than file limit? - return LFS2_ERR_FBIG; - } + return lfs2_file_flushedread(lfs2, file, buffer, size); +} - if (!(file->flags & LFS2_F_WRITING) && file->pos > file->ctz.size) { - // fill with zeros - lfs2_off_t pos = file->pos; - file->pos = file->ctz.size; - while (file->pos < pos) { - lfs2_ssize_t res = lfs2_file_rawwrite(lfs2, file, &(uint8_t){0}, 1); - if (res < 0) { - return res; - } - } - } +#ifndef LFS2_READONLY +static lfs2_ssize_t lfs2_file_flushedwrite(lfs2_t *lfs2, lfs2_file_t *file, + const void *buffer, lfs2_size_t size) { + const uint8_t *data = buffer; + lfs2_size_t nsize = size; if ((file->flags & LFS2_F_INLINE) && lfs2_max(file->pos+nsize, file->ctz.size) > lfs2_min(0x3fe, lfs2_min( - lfs2->cfg->cache_size, lfs2->cfg->block_size/8))) { + lfs2->cfg->cache_size, + (lfs2->cfg->metadata_max ? + lfs2->cfg->metadata_max : lfs2->cfg->block_size) / 8))) { // inline file doesn't fit anymore int err = lfs2_file_outline(lfs2, file); if (err) { @@ -3043,29 +3404,72 @@ static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, lfs2_alloc_ack(lfs2); } - file->flags &= ~LFS2_F_ERRED; return size; } -#endif -static lfs2_soff_t lfs2_file_rawseek(lfs2_t *lfs2, lfs2_file_t *file, - lfs2_soff_t off, int whence) { -#ifndef LFS2_READONLY - // write out everything beforehand, may be noop if rdonly - int err = lfs2_file_flush(lfs2, file); - if (err) { - return err; +static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, + const void *buffer, lfs2_size_t size) { + LFS2_ASSERT((file->flags & LFS2_O_WRONLY) == LFS2_O_WRONLY); + + if (file->flags & LFS2_F_READING) { + // drop any reads + int err = lfs2_file_flush(lfs2, file); + if (err) { + return err; + } + } + + if ((file->flags & LFS2_O_APPEND) && file->pos < file->ctz.size) { + file->pos = file->ctz.size; + } + + if (file->pos + size > lfs2->file_max) { + // Larger than file limit? + return LFS2_ERR_FBIG; + } + + if (!(file->flags & LFS2_F_WRITING) && file->pos > file->ctz.size) { + // fill with zeros + lfs2_off_t pos = file->pos; + file->pos = file->ctz.size; + + while (file->pos < pos) { + lfs2_ssize_t res = lfs2_file_flushedwrite(lfs2, file, &(uint8_t){0}, 1); + if (res < 0) { + return res; + } + } + } + + lfs2_ssize_t nsize = lfs2_file_flushedwrite(lfs2, file, buffer, size); + if (nsize < 0) { + return nsize; } + + file->flags &= ~LFS2_F_ERRED; + return nsize; +} #endif +static lfs2_soff_t lfs2_file_rawseek(lfs2_t *lfs2, lfs2_file_t *file, + lfs2_soff_t off, int whence) { // find new pos lfs2_off_t npos = file->pos; if (whence == LFS2_SEEK_SET) { npos = off; } else if (whence == LFS2_SEEK_CUR) { - npos = file->pos + off; + if ((lfs2_soff_t)file->pos + off < 0) { + return LFS2_ERR_INVAL; + } else { + npos = file->pos + off; + } } else if (whence == LFS2_SEEK_END) { - npos = file->ctz.size + off; + lfs2_soff_t res = lfs2_file_rawsize(lfs2, file) + off; + if (res < 0) { + return LFS2_ERR_INVAL; + } else { + npos = res; + } } if (npos > lfs2->file_max) { @@ -3073,6 +3477,38 @@ static lfs2_soff_t lfs2_file_rawseek(lfs2_t *lfs2, lfs2_file_t *file, return LFS2_ERR_INVAL; } + if (file->pos == npos) { + // noop - position has not changed + return npos; + } + + // if we're only reading and our new offset is still in the file's cache + // we can avoid flushing and needing to reread the data + if ( +#ifndef LFS2_READONLY + !(file->flags & LFS2_F_WRITING) +#else + true +#endif + ) { + int oindex = lfs2_ctz_index(lfs2, &(lfs2_off_t){file->pos}); + lfs2_off_t noff = npos; + int nindex = lfs2_ctz_index(lfs2, &noff); + if (oindex == nindex + && noff >= file->cache.off + && noff < file->cache.off + file->cache.size) { + file->pos = npos; + file->off = noff; + return npos; + } + } + + // write out everything beforehand, may be noop if rdonly + int err = lfs2_file_flush(lfs2, file); + if (err) { + return err; + } + // update pos file->pos = npos; return npos; @@ -3103,21 +3539,22 @@ static int lfs2_file_rawtruncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t siz return err; } + // need to set pos/block/off consistently so seeking back to + // the old position does not get confused + file->pos = size; file->ctz.head = file->block; file->ctz.size = size; file->flags |= LFS2_F_DIRTY | LFS2_F_READING; } else if (size > oldsize) { // flush+seek if not already at end - if (file->pos != oldsize) { - lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, 0, LFS2_SEEK_END); - if (res < 0) { - return (int)res; - } + lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, 0, LFS2_SEEK_END); + if (res < 0) { + return (int)res; } // fill with zeros while (file->pos < size) { - lfs2_ssize_t res = lfs2_file_rawwrite(lfs2, file, &(uint8_t){0}, 1); + res = lfs2_file_rawwrite(lfs2, file, &(uint8_t){0}, 1); if (res < 0) { return (int)res; } @@ -3208,7 +3645,10 @@ static int lfs2_rawremove(lfs2_t *lfs2, const char *path) { } // mark fs as orphaned - lfs2_fs_preporphans(lfs2, +1); + err = lfs2_fs_preporphans(lfs2, +1); + if (err) { + return err; + } // I know it's crazy but yes, dir can be changed by our parent's // commit (if predecessor is child) @@ -3228,7 +3668,10 @@ static int lfs2_rawremove(lfs2_t *lfs2, const char *path) { lfs2->mlist = dir.next; if (lfs2_tag_type3(tag) == LFS2_TYPE_DIR) { // fix orphan - lfs2_fs_preporphans(lfs2, -1); + err = lfs2_fs_preporphans(lfs2, -1); + if (err) { + return err; + } err = lfs2_fs_pred(lfs2, dir.m.pair, &cwd); if (err) { @@ -3314,7 +3757,10 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath } // mark fs as orphaned - lfs2_fs_preporphans(lfs2, +1); + err = lfs2_fs_preporphans(lfs2, +1); + if (err) { + return err; + } // I know it's crazy but yes, dir can be changed by our parent's // commit (if predecessor is child) @@ -3355,9 +3801,13 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath } lfs2->mlist = prevdir.next; - if (prevtag != LFS2_ERR_NOENT && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) { + if (prevtag != LFS2_ERR_NOENT + && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) { // fix orphan - lfs2_fs_preporphans(lfs2, -1); + err = lfs2_fs_preporphans(lfs2, -1); + if (err) { + return err; + } err = lfs2_fs_pred(lfs2, prevdir.m.pair, &newcwd); if (err) { @@ -3538,6 +3988,8 @@ static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs2->attr_max = LFS2_ATTR_MAX; } + LFS2_ASSERT(lfs2->cfg->metadata_max <= lfs2->cfg->block_size); + // setup default state lfs2->root[0] = LFS2_BLOCK_NULL; lfs2->root[1] = LFS2_BLOCK_NULL; @@ -3618,12 +4070,6 @@ static int lfs2_rawformat(lfs2_t *lfs2, const struct lfs2_config *cfg) { goto cleanup; } - // sanity check that fetch works - err = lfs2_dir_fetch(lfs2, &root, (const lfs2_block_t[2]){0, 1}); - if (err) { - goto cleanup; - } - // force compaction to prevent accidentally mounting any // older version of littlefs that may live on disk root.erased = false; @@ -3631,6 +4077,12 @@ static int lfs2_rawformat(lfs2_t *lfs2, const struct lfs2_config *cfg) { if (err) { goto cleanup; } + + // sanity check that fetch works + err = lfs2_dir_fetch(lfs2, &root, (const lfs2_block_t[2]){0, 1}); + if (err) { + goto cleanup; + } } cleanup: @@ -3730,6 +4182,20 @@ static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs2->attr_max = superblock.attr_max; } + + if (superblock.block_count != lfs2->cfg->block_count) { + LFS2_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")", + superblock.block_count, lfs2->cfg->block_count); + err = LFS2_ERR_INVAL; + goto cleanup; + } + + if (superblock.block_size != lfs2->cfg->block_size) { + LFS2_ERROR("Invalid block size (%"PRIu32" != %"PRIu32")", + superblock.block_count, lfs2->cfg->block_count); + err = LFS2_ERR_INVAL; + goto cleanup; + } } // has gstate? @@ -3957,108 +4423,13 @@ static lfs2_stag_t lfs2_fs_parent(lfs2_t *lfs2, const lfs2_block_t pair[2], #endif #ifndef LFS2_READONLY -static int lfs2_fs_relocate(lfs2_t *lfs2, - const lfs2_block_t oldpair[2], lfs2_block_t newpair[2]) { - // update internal root - if (lfs2_pair_cmp(oldpair, lfs2->root) == 0) { - lfs2->root[0] = newpair[0]; - lfs2->root[1] = newpair[1]; - } - - // update internally tracked dirs - for (struct lfs2_mlist *d = lfs2->mlist; d; d = d->next) { - if (lfs2_pair_cmp(oldpair, d->m.pair) == 0) { - d->m.pair[0] = newpair[0]; - d->m.pair[1] = newpair[1]; - } - - if (d->type == LFS2_TYPE_DIR && - lfs2_pair_cmp(oldpair, ((lfs2_dir_t*)d)->head) == 0) { - ((lfs2_dir_t*)d)->head[0] = newpair[0]; - ((lfs2_dir_t*)d)->head[1] = newpair[1]; - } - } - - // find parent - lfs2_mdir_t parent; - lfs2_stag_t tag = lfs2_fs_parent(lfs2, oldpair, &parent); - if (tag < 0 && tag != LFS2_ERR_NOENT) { - return tag; - } - - if (tag != LFS2_ERR_NOENT) { - // update disk, this creates a desync - lfs2_fs_preporphans(lfs2, +1); - - // fix pending move in this pair? this looks like an optimization but - // is in fact _required_ since relocating may outdate the move. - uint16_t moveid = 0x3ff; - if (lfs2_gstate_hasmovehere(&lfs2->gstate, parent.pair)) { - moveid = lfs2_tag_id(lfs2->gstate.tag); - LFS2_DEBUG("Fixing move while relocating " - "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", - parent.pair[0], parent.pair[1], moveid); - lfs2_fs_prepmove(lfs2, 0x3ff, NULL); - if (moveid < lfs2_tag_id(tag)) { - tag -= LFS2_MKTAG(0, 1, 0); - } - } - - lfs2_pair_tole32(newpair); - int err = lfs2_dir_commit(lfs2, &parent, LFS2_MKATTRS( - {LFS2_MKTAG_IF(moveid != 0x3ff, - LFS2_TYPE_DELETE, moveid, 0), NULL}, - {tag, newpair})); - lfs2_pair_fromle32(newpair); - if (err) { - return err; - } - - // next step, clean up orphans - lfs2_fs_preporphans(lfs2, -1); - } - - // find pred - int err = lfs2_fs_pred(lfs2, oldpair, &parent); - if (err && err != LFS2_ERR_NOENT) { - return err; - } - - // if we can't find dir, it must be new - if (err != LFS2_ERR_NOENT) { - // fix pending move in this pair? this looks like an optimization but - // is in fact _required_ since relocating may outdate the move. - uint16_t moveid = 0x3ff; - if (lfs2_gstate_hasmovehere(&lfs2->gstate, parent.pair)) { - moveid = lfs2_tag_id(lfs2->gstate.tag); - LFS2_DEBUG("Fixing move while relocating " - "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", - parent.pair[0], parent.pair[1], moveid); - lfs2_fs_prepmove(lfs2, 0x3ff, NULL); - } - - // replace bad pair, either we clean up desync, or no desync occured - lfs2_pair_tole32(newpair); - err = lfs2_dir_commit(lfs2, &parent, LFS2_MKATTRS( - {LFS2_MKTAG_IF(moveid != 0x3ff, - LFS2_TYPE_DELETE, moveid, 0), NULL}, - {LFS2_MKTAG(LFS2_TYPE_TAIL + parent.split, 0x3ff, 8), newpair})); - lfs2_pair_fromle32(newpair); - if (err) { - return err; - } - } - - return 0; -} -#endif - -#ifndef LFS2_READONLY -static void lfs2_fs_preporphans(lfs2_t *lfs2, int8_t orphans) { +static int lfs2_fs_preporphans(lfs2_t *lfs2, int8_t orphans) { LFS2_ASSERT(lfs2_tag_size(lfs2->gstate.tag) > 0 || orphans >= 0); lfs2->gstate.tag += orphans; lfs2->gstate.tag = ((lfs2->gstate.tag & ~LFS2_MKTAG(0x800, 0, 0)) | ((uint32_t)lfs2_gstate_hasorphans(&lfs2->gstate) << 31)); + + return 0; } #endif @@ -4105,78 +4476,129 @@ static int lfs2_fs_demove(lfs2_t *lfs2) { #endif #ifndef LFS2_READONLY -static int lfs2_fs_deorphan(lfs2_t *lfs2) { +static int lfs2_fs_deorphan(lfs2_t *lfs2, bool powerloss) { if (!lfs2_gstate_hasorphans(&lfs2->gstate)) { return 0; } - // Fix any orphans - lfs2_mdir_t pdir = {.split = true, .tail = {0, 1}}; - lfs2_mdir_t dir; - - // iterate over all directory directory entries - while (!lfs2_pair_isnull(pdir.tail)) { - int err = lfs2_dir_fetch(lfs2, &dir, pdir.tail); - if (err) { - return err; - } + int8_t found = 0; +restart: + { + // Fix any orphans + lfs2_mdir_t pdir = {.split = true, .tail = {0, 1}}; + lfs2_mdir_t dir; - // check head blocks for orphans - if (!pdir.split) { - // check if we have a parent - lfs2_mdir_t parent; - lfs2_stag_t tag = lfs2_fs_parent(lfs2, pdir.tail, &parent); - if (tag < 0 && tag != LFS2_ERR_NOENT) { - return tag; + // iterate over all directory directory entries + while (!lfs2_pair_isnull(pdir.tail)) { + int err = lfs2_dir_fetch(lfs2, &dir, pdir.tail); + if (err) { + return err; } - if (tag == LFS2_ERR_NOENT) { - // we are an orphan - LFS2_DEBUG("Fixing orphan {0x%"PRIx32", 0x%"PRIx32"}", - pdir.tail[0], pdir.tail[1]); - - err = lfs2_dir_drop(lfs2, &pdir, &dir); - if (err) { - return err; + // check head blocks for orphans + if (!pdir.split) { + // check if we have a parent + lfs2_mdir_t parent; + lfs2_stag_t tag = lfs2_fs_parent(lfs2, pdir.tail, &parent); + if (tag < 0 && tag != LFS2_ERR_NOENT) { + return tag; } - // refetch tail - continue; - } + // note we only check for full orphans if we may have had a + // power-loss, otherwise orphans are created intentionally + // during operations such as lfs2_mkdir + if (tag == LFS2_ERR_NOENT && powerloss) { + // we are an orphan + LFS2_DEBUG("Fixing orphan {0x%"PRIx32", 0x%"PRIx32"}", + pdir.tail[0], pdir.tail[1]); - lfs2_block_t pair[2]; - lfs2_stag_t res = lfs2_dir_get(lfs2, &parent, - LFS2_MKTAG(0x7ff, 0x3ff, 0), tag, pair); - if (res < 0) { - return res; - } - lfs2_pair_fromle32(pair); - - if (!lfs2_pair_sync(pair, pdir.tail)) { - // we have desynced - LFS2_DEBUG("Fixing half-orphan {0x%"PRIx32", 0x%"PRIx32"} " - "-> {0x%"PRIx32", 0x%"PRIx32"}", - pdir.tail[0], pdir.tail[1], pair[0], pair[1]); - - lfs2_pair_tole32(pair); - err = lfs2_dir_commit(lfs2, &pdir, LFS2_MKATTRS( - {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), pair})); - lfs2_pair_fromle32(pair); - if (err) { - return err; + // steal state + err = lfs2_dir_getgstate(lfs2, &dir, &lfs2->gdelta); + if (err) { + return err; + } + + // steal tail + lfs2_pair_tole32(dir.tail); + int state = lfs2_dir_orphaningcommit(lfs2, &pdir, LFS2_MKATTRS( + {LFS2_MKTAG(LFS2_TYPE_TAIL + dir.split, 0x3ff, 8), + dir.tail})); + lfs2_pair_fromle32(dir.tail); + if (state < 0) { + return state; + } + + found += 1; + + // did our commit create more orphans? + if (state == LFS2_OK_ORPHANED) { + goto restart; + } + + // refetch tail + continue; } - // refetch tail - continue; + if (tag != LFS2_ERR_NOENT) { + lfs2_block_t pair[2]; + lfs2_stag_t state = lfs2_dir_get(lfs2, &parent, + LFS2_MKTAG(0x7ff, 0x3ff, 0), tag, pair); + if (state < 0) { + return state; + } + lfs2_pair_fromle32(pair); + + if (!lfs2_pair_sync(pair, pdir.tail)) { + // we have desynced + LFS2_DEBUG("Fixing half-orphan " + "{0x%"PRIx32", 0x%"PRIx32"} " + "-> {0x%"PRIx32", 0x%"PRIx32"}", + pdir.tail[0], pdir.tail[1], pair[0], pair[1]); + + // fix pending move in this pair? this looks like an + // optimization but is in fact _required_ since + // relocating may outdate the move. + uint16_t moveid = 0x3ff; + if (lfs2_gstate_hasmovehere(&lfs2->gstate, pdir.pair)) { + moveid = lfs2_tag_id(lfs2->gstate.tag); + LFS2_DEBUG("Fixing move while fixing orphans " + "{0x%"PRIx32", 0x%"PRIx32"} 0x%"PRIx16"\n", + pdir.pair[0], pdir.pair[1], moveid); + lfs2_fs_prepmove(lfs2, 0x3ff, NULL); + } + + lfs2_pair_tole32(pair); + state = lfs2_dir_orphaningcommit(lfs2, &pdir, LFS2_MKATTRS( + {LFS2_MKTAG_IF(moveid != 0x3ff, + LFS2_TYPE_DELETE, moveid, 0), NULL}, + {LFS2_MKTAG(LFS2_TYPE_SOFTTAIL, 0x3ff, 8), + pair})); + lfs2_pair_fromle32(pair); + if (state < 0) { + return state; + } + + found += 1; + + // did our commit create more orphans? + if (state == LFS2_OK_ORPHANED) { + goto restart; + } + + // refetch tail + continue; + } + } } - } - pdir = dir; + pdir = dir; + } } // mark orphans as fixed - lfs2_fs_preporphans(lfs2, -lfs2_gstate_getorphans(&lfs2->gstate)); - return 0; + return lfs2_fs_preporphans(lfs2, -lfs2_min( + lfs2_gstate_getorphans(&lfs2->gstate), + found)); } #endif @@ -4187,7 +4609,7 @@ static int lfs2_fs_forceconsistency(lfs2_t *lfs2) { return err; } - err = lfs2_fs_deorphan(lfs2); + err = lfs2_fs_deorphan(lfs2, true); if (err) { return err; } @@ -4725,7 +5147,7 @@ static int lfs2_rawmigrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs21_entry_tole32(&entry1.d); err = lfs2_dir_commit(lfs2, &dir2, LFS2_MKATTRS( - {LFS2_MKTAG(LFS2_TYPE_CREATE, id, 0)}, + {LFS2_MKTAG(LFS2_TYPE_CREATE, id, 0), NULL}, {LFS2_MKTAG_IF_ELSE(isdir, LFS2_TYPE_DIR, id, entry1.d.nlen, LFS2_TYPE_REG, id, entry1.d.nlen), @@ -4830,7 +5252,7 @@ static int lfs2_rawmigrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs2_superblock_tole32(&superblock); err = lfs2_dir_commit(lfs2, &dir2, LFS2_MKATTRS( - {LFS2_MKTAG(LFS2_TYPE_CREATE, 0, 0)}, + {LFS2_MKTAG(LFS2_TYPE_CREATE, 0, 0), NULL}, {LFS2_MKTAG(LFS2_TYPE_SUPERBLOCK, 0, 8), "littlefs"}, {LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), &superblock})); @@ -5044,6 +5466,7 @@ int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type) { } #endif +#ifndef LFS2_NO_MALLOC int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags) { int err = LFS2_LOCK(lfs2->cfg); if (err) { @@ -5059,6 +5482,7 @@ int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags) LFS2_UNLOCK(lfs2->cfg); return err; } +#endif int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags, diff --git a/lib/littlefs/lfs2.h b/lib/littlefs/lfs2.h index f3b66d76ff278..715764f7ce982 100644 --- a/lib/littlefs/lfs2.h +++ b/lib/littlefs/lfs2.h @@ -1,6 +1,7 @@ /* * The little filesystem * + * Copyright (c) 2022, The littlefs authors. * Copyright (c) 2017, Arm Limited. All rights reserved. * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,7 +23,7 @@ extern "C" // Software library version // Major (top-nibble), incremented on backwards incompatible changes // Minor (bottom-nibble), incremented on feature additions -#define LFS2_VERSION 0x00020003 +#define LFS2_VERSION 0x00020005 #define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16)) #define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0)) @@ -159,49 +160,49 @@ struct lfs2_config { // information to the block device operations void *context; - // Read a region in a block. Negative error codes are propogated + // Read a region in a block. Negative error codes are propagated // to the user. int (*read)(const struct lfs2_config *c, lfs2_block_t block, lfs2_off_t off, void *buffer, lfs2_size_t size); // Program a region in a block. The block must have previously - // been erased. Negative error codes are propogated to the user. + // been erased. Negative error codes are propagated to the user. // May return LFS2_ERR_CORRUPT if the block should be considered bad. int (*prog)(const struct lfs2_config *c, lfs2_block_t block, lfs2_off_t off, const void *buffer, lfs2_size_t size); // Erase a block. A block must be erased before being programmed. // The state of an erased block is undefined. Negative error codes - // are propogated to the user. + // are propagated to the user. // May return LFS2_ERR_CORRUPT if the block should be considered bad. int (*erase)(const struct lfs2_config *c, lfs2_block_t block); // Sync the state of the underlying block device. Negative error codes - // are propogated to the user. + // are propagated to the user. int (*sync)(const struct lfs2_config *c); #ifdef LFS2_THREADSAFE // Lock the underlying block device. Negative error codes - // are propogated to the user. + // are propagated to the user. int (*lock)(const struct lfs2_config *c); // Unlock the underlying block device. Negative error codes - // are propogated to the user. + // are propagated to the user. int (*unlock)(const struct lfs2_config *c); #endif - // Minimum size of a block read. All read operations will be a + // Minimum size of a block read in bytes. All read operations will be a // multiple of this value. lfs2_size_t read_size; - // Minimum size of a block program. All program operations will be a - // multiple of this value. + // Minimum size of a block program in bytes. All program operations will be + // a multiple of this value. lfs2_size_t prog_size; - // Size of an erasable block. This does not impact ram consumption and - // may be larger than the physical erase size. However, non-inlined files - // take up at minimum one block. Must be a multiple of the read - // and program sizes. + // Size of an erasable block in bytes. This does not impact ram consumption + // and may be larger than the physical erase size. However, non-inlined + // files take up at minimum one block. Must be a multiple of the read and + // program sizes. lfs2_size_t block_size; // Number of erasable blocks on the device. @@ -215,11 +216,11 @@ struct lfs2_config { // Set to -1 to disable block-level wear-leveling. int32_t block_cycles; - // Size of block caches. Each cache buffers a portion of a block in RAM. - // The littlefs needs a read cache, a program cache, and one additional + // Size of block caches in bytes. Each cache buffers a portion of a block in + // RAM. The littlefs needs a read cache, a program cache, and one additional // cache per file. Larger caches can improve performance by storing more - // data and reducing the number of disk accesses. Must be a multiple of - // the read and program sizes, and a factor of the block size. + // data and reducing the number of disk accesses. Must be a multiple of the + // read and program sizes, and a factor of the block size. lfs2_size_t cache_size; // Size of the lookahead buffer in bytes. A larger lookahead buffer @@ -256,6 +257,12 @@ struct lfs2_config { // larger attributes size but must be <= LFS2_ATTR_MAX. Defaults to // LFS2_ATTR_MAX when zero. lfs2_size_t attr_max; + + // Optional upper limit on total space given to metadata pairs in bytes. On + // devices with large blocks (e.g. 128kB) setting this to a low size (2-8kB) + // can help bound the metadata compaction time. Must be <= block_size. + // Defaults to block_size when zero. + lfs2_size_t metadata_max; }; // File info structure @@ -479,7 +486,7 @@ int lfs2_stat(lfs2_t *lfs2, const char *path, struct lfs2_info *info); // Returns the size of the attribute, or a negative error code on failure. // Note, the returned size is the size of the attribute on disk, irrespective // of the size of the buffer. This can be used to dynamically allocate a buffer -// or check for existance. +// or check for existence. lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path, uint8_t type, void *buffer, lfs2_size_t size); @@ -507,6 +514,7 @@ int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type); /// File operations /// +#ifndef LFS2_NO_MALLOC // Open a file // // The mode that the file is opened in is determined by the flags, which @@ -516,6 +524,10 @@ int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type); int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags); +// if LFS2_NO_MALLOC is defined, lfs2_file_open() will fail with LFS2_ERR_NOMEM +// thus use lfs2_file_opencfg() with config.buffer set. +#endif + // Open a file with extra configuration // // The mode that the file is opened in is determined by the flags, which diff --git a/lib/littlefs/lfs2_util.c b/lib/littlefs/lfs2_util.c index 083a99c36cf1e..c9850e78869c3 100644 --- a/lib/littlefs/lfs2_util.c +++ b/lib/littlefs/lfs2_util.c @@ -1,6 +1,7 @@ /* * lfs2 util functions * + * Copyright (c) 2022, The littlefs authors. * Copyright (c) 2017, Arm Limited. All rights reserved. * SPDX-License-Identifier: BSD-3-Clause */ diff --git a/lib/littlefs/lfs2_util.h b/lib/littlefs/lfs2_util.h index 70bca717c93ce..6a4c8ffb50471 100644 --- a/lib/littlefs/lfs2_util.h +++ b/lib/littlefs/lfs2_util.h @@ -1,6 +1,7 @@ /* * lfs2 utility functions * + * Copyright (c) 2022, The littlefs authors. * Copyright (c) 2017, Arm Limited. All rights reserved. * SPDX-License-Identifier: BSD-3-Clause */ @@ -49,6 +50,7 @@ extern "C" // code footprint // Logging functions +#ifndef LFS2_TRACE #ifdef LFS2_YES_TRACE #define LFS2_TRACE_(fmt, ...) \ printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) @@ -56,7 +58,9 @@ extern "C" #else #define LFS2_TRACE(...) #endif +#endif +#ifndef LFS2_DEBUG #ifndef LFS2_NO_DEBUG #define LFS2_DEBUG_(fmt, ...) \ printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) @@ -64,7 +68,9 @@ extern "C" #else #define LFS2_DEBUG(...) #endif +#endif +#ifndef LFS2_WARN #ifndef LFS2_NO_WARN #define LFS2_WARN_(fmt, ...) \ printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) @@ -72,7 +78,9 @@ extern "C" #else #define LFS2_WARN(...) #endif +#endif +#ifndef LFS2_ERROR #ifndef LFS2_NO_ERROR #define LFS2_ERROR_(fmt, ...) \ printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__) @@ -80,13 +88,16 @@ extern "C" #else #define LFS2_ERROR(...) #endif +#endif // Runtime assertions +#ifndef LFS2_ASSERT #ifndef LFS2_NO_ASSERT #define LFS2_ASSERT(test) assert(test) #else #define LFS2_ASSERT(test) #endif +#endif // Builtin functions, these may be replaced by more efficient diff --git a/lib/oofatfs/ffconf.h b/lib/oofatfs/ffconf.h index 2967244118ab7..fbb568f7c427b 100644 --- a/lib/oofatfs/ffconf.h +++ b/lib/oofatfs/ffconf.h @@ -6,7 +6,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2013-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/lib/re1.5/re1.5.h b/lib/re1.5/re1.5.h index 995e2d4d21836..43a04161602be 100644 --- a/lib/re1.5/re1.5.h +++ b/lib/re1.5/re1.5.h @@ -132,6 +132,7 @@ Sub *update(Sub*, int, const char*); void decref(Sub*); struct Subject { + const char *begin_line; const char *begin; const char *end; }; diff --git a/lib/re1.5/recursiveloop.c b/lib/re1.5/recursiveloop.c index f8cb92629200a..17ecea3378ef4 100644 --- a/lib/re1.5/recursiveloop.c +++ b/lib/re1.5/recursiveloop.c @@ -68,7 +68,7 @@ recursiveloop(char *pc, const char *sp, Subject *input, const char **subp, int n subp[off] = old; return 0; case Bol: - if(sp != input->begin) + if(sp != input->begin_line) return 0; continue; case Eol: diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 0759f70c0ce2a..1ca523bae2ebb 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -139,6 +139,10 @@ msgstr "" msgid "%q index out of range" msgstr "" +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "" + #: shared-module/bitbangio/SPI.c msgid "%q init failed" msgstr "" @@ -214,7 +218,7 @@ msgstr "" msgid "%q must be of type %q or %q, not %q" msgstr "" -#: py/argcheck.c py/obj.c py/objstrunicode.c shared-module/synthio/__init__.c +#: py/argcheck.c py/objstrunicode.c shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "" @@ -417,6 +421,10 @@ msgstr "" msgid "'yield' outside function" msgstr "" +#: py/compile.c +msgid "* arg after **" +msgstr "" + #: py/compile.c msgid "*x must be assignment target" msgstr "" @@ -840,10 +848,6 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" -#: py/persistentcode.c -msgid "Corrupt .mpy file" -msgstr "" - #: ports/espressif/common-hal/neopixel_write/__init__.c msgid "Could not retrieve clock" msgstr "" @@ -1138,12 +1142,6 @@ msgstr "" msgid "In-buffer elements must be <= 4 bytes long" msgstr "" -#: py/persistentcode.c -msgid "" -"Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/" -"mpy-update for more info." -msgstr "" - #: shared-bindings/_pew/PewPew.c msgid "Incorrect buffer size" msgstr "" @@ -1490,7 +1488,7 @@ msgstr "" msgid "No in or out in program" msgstr "" -#: shared-bindings/time/__init__.c +#: py/objint.c shared-bindings/time/__init__.c msgid "No long integer support" msgstr "" @@ -2498,6 +2496,10 @@ msgstr "" msgid "array/bytes required on right side" msgstr "" +#: py/asmxtensa.c +msgid "asm overflow" +msgstr "" + #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get (arg)min/(arg)max of empty sequence" msgstr "" @@ -2587,6 +2589,10 @@ msgstr "" msgid "buffer too small for requested bytes" msgstr "" +#: py/emitbc.c +msgid "bytecode overflow" +msgstr "" + #: py/objarray.c msgid "bytes length not a multiple of item size" msgstr "" @@ -2632,7 +2638,7 @@ msgstr "" msgid "can't cancel self" msgstr "" -#: py/obj.c py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/objint.c py/runtime.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" @@ -2641,6 +2647,11 @@ msgstr "" msgid "can't convert %s to complex" msgstr "" +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "" + #: py/objstr.c msgid "can't convert '%q' object to %q implicitly" msgstr "" @@ -2650,11 +2661,11 @@ msgid "can't convert complex to float" msgstr "" #: py/obj.c -msgid "can't convert to %q" +msgid "can't convert to complex" msgstr "" #: py/obj.c -msgid "can't convert to complex" +msgid "can't convert to float" msgstr "" #: py/runtime.c @@ -2681,14 +2692,6 @@ msgstr "" msgid "can't do truncated division of a complex number" msgstr "" -#: py/compile.c -msgid "can't have multiple **x" -msgstr "" - -#: py/compile.c -msgid "can't have multiple *x" -msgstr "" - #: py/emitnative.c msgid "can't implicitly convert '%q' to 'bool'" msgstr "" @@ -2743,6 +2746,10 @@ msgid "" "can't switch from manual field specification to automatic field numbering" msgstr "" +#: extmod/moduasyncio.c +msgid "can't wait" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "cannot assign new shape" msgstr "" @@ -2839,10 +2846,6 @@ msgstr "" msgid "compression header" msgstr "" -#: py/parse.c -msgid "constant must be an integer" -msgstr "" - #: py/emitnative.c msgid "conversion to object" msgstr "" @@ -3179,7 +3182,11 @@ msgid "import * not at module level" msgstr "" #: py/persistentcode.c -msgid "incompatible native .mpy architecture" +msgid "incompatible .mpy arch" +msgstr "" + +#: py/persistentcode.c +msgid "incompatible .mpy file" msgstr "" #: py/objstr.c @@ -3208,6 +3215,10 @@ msgstr "" msgid "index out of range" msgstr "" +#: py/obj.c +msgid "indices must be integers" +msgstr "" + #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" @@ -3341,10 +3352,6 @@ msgstr "" msgid "invalid exception" msgstr "" -#: extmod/modframebuf.c -msgid "invalid format" -msgstr "" - #: py/objstr.c msgid "invalid format specifier" msgstr "" @@ -3406,10 +3413,6 @@ msgstr "" msgid "keyword argument(s) not yet implemented - use normal args instead" msgstr "" -#: py/bc.c -msgid "keywords must be strings" -msgstr "" - #: py/emitinlinethumb.c py/emitinlinextensa.c msgid "label '%q' not defined" msgstr "" @@ -3634,14 +3637,6 @@ msgstr "" msgid "non-hex digit found" msgstr "" -#: py/compile.c -msgid "non-keyword arg after */**" -msgstr "" - -#: py/compile.c -msgid "non-keyword arg after keyword arg" -msgstr "" - #: ports/nrf/common-hal/_bleio/Adapter.c msgid "non-zero timeout must be > 0.01" msgstr "" @@ -3654,6 +3649,10 @@ msgstr "" msgid "not a 128-bit UUID" msgstr "" +#: py/parse.c +msgid "not a constant" +msgstr "" + #: py/objstr.c msgid "not all arguments converted during string formatting" msgstr "" @@ -3892,6 +3891,14 @@ msgstr "" msgid "port must be >= 0" msgstr "" +#: py/compile.c +msgid "positional arg after **" +msgstr "" + +#: py/compile.c +msgid "positional arg after keyword arg" +msgstr "" + #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" msgstr "" @@ -3920,6 +3927,11 @@ msgstr "" msgid "relative import" msgstr "" +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "" + #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" msgstr "" @@ -4114,6 +4126,10 @@ msgstr "" msgid "tobytes can be invoked for dense arrays only" msgstr "" +#: py/compile.c +msgid "too many args" +msgstr "" + #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" msgstr "" @@ -4139,6 +4155,10 @@ msgstr "" msgid "trapz is defined for 1D iterables" msgstr "" +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "" + #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" diff --git a/main.c b/main.c index 122f0791294cc..a22a7eba19c0c 100644 --- a/main.c +++ b/main.c @@ -418,8 +418,8 @@ STATIC bool run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { }; #if CIRCUITPY_FULL_BUILD static const char *const double_extension_filenames[] = { - "code.txt.py", "code.py.txt", "code.txt.txt","code.py.py", - "main.txt.py", "main.py.txt", "main.txt.txt","main.py.py" + "code.txt.py", "code.py.txt", "code.txt.txt", "code.py.py", + "main.txt.py", "main.py.txt", "main.txt.txt", "main.py.py" }; #endif @@ -992,9 +992,9 @@ int __attribute__((used)) main(void) { #if CIRCUITPY_BOOT_COUNTER // Increment counter before possibly entering safe mode - common_hal_nvm_bytearray_get_bytes(&common_hal_mcu_nvm_obj,0,1,&value_out); + common_hal_nvm_bytearray_get_bytes(&common_hal_mcu_nvm_obj, 0, 1, &value_out); ++value_out; - common_hal_nvm_bytearray_set_bytes(&common_hal_mcu_nvm_obj,0,&value_out,1); + common_hal_nvm_bytearray_set_bytes(&common_hal_mcu_nvm_obj, 0, &value_out, 1); #endif // Start the debug serial diff --git a/mpy-cross/gccollect.c b/mpy-cross/gccollect.c index 79c47f3b68b34..72d4204c28980 100644 --- a/mpy-cross/gccollect.c +++ b/mpy-cross/gccollect.c @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: Copyright (c) 2013-2014 Damien P. George -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include diff --git a/mpy-cross/main.c b/mpy-cross/main.c index 077e84f4733a3..88d84915f8297 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -1,13 +1,35 @@ -// SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ #include #include #include #include +#include "py/builtin.h" #include "py/compile.h" #include "py/persistentcode.h" #include "py/runtime.h" @@ -51,7 +73,8 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha #endif mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); - mp_raw_code_t *rc = mp_compile_to_raw_code(&parse_tree, source_name, false); + mp_module_context_t *ctx = m_new_obj(mp_module_context_t); + mp_compiled_module_t cm = mp_compile_to_raw_code(&parse_tree, source_name, false, ctx); vstr_t vstr; vstr_init(&vstr, 16); @@ -62,7 +85,7 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha } else { vstr_add_str(&vstr, output_file); } - mp_raw_code_save_file(rc, vstr_null_terminated_str(&vstr)); + mp_raw_code_save_file(&cm, vstr_null_terminated_str(&vstr)); vstr_clear(&vstr); nlr_pop(); @@ -86,8 +109,7 @@ STATIC int usage(char **argv) { "\n" "Target specific options:\n" "-msmall-int-bits=number : set the maximum bits used to encode a small-int\n" - "-mno-unicode : don't support unicode in compiled strings\n" - "-march= : set architecture for native emitter; x86, x64, armv6, armv7m, armv7em, armv7emsp, armv7emdp, xtensa, xtensawin\n" + "-march= : set architecture for native emitter; x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp, armv7emdp, xtensa, xtensawin\n" "\n" "Implementation specific options:\n", argv[0] ); @@ -181,7 +203,6 @@ MP_NOINLINE int main_(int argc, char **argv) { // set default compiler configuration mp_dynamic_compiler.small_int_bits = 31; - mp_dynamic_compiler.py_builtins_str_unicode = 1; #if defined(__i386__) mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86; mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_X86; @@ -239,10 +260,6 @@ MP_NOINLINE int main_(int argc, char **argv) { return usage(argv); } // TODO check that small_int_bits is within range of host's capabilities - } else if (strcmp(argv[a], "-mno-unicode") == 0) { - mp_dynamic_compiler.py_builtins_str_unicode = 0; - } else if (strcmp(argv[a], "-municode") == 0) { - mp_dynamic_compiler.py_builtins_str_unicode = 1; } else if (strncmp(argv[a], "-march=", sizeof("-march=") - 1) == 0) { const char *arch = argv[a] + sizeof("-march=") - 1; if (strcmp(arch, "x86") == 0) { @@ -254,6 +271,9 @@ MP_NOINLINE int main_(int argc, char **argv) { } else if (strcmp(arch, "armv6") == 0) { mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV6; mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_ARM_THUMB_FP; + } else if (strcmp(arch, "armv6m") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV6M; + mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_ARM_THUMB_FP; // need to be conservative so this code can run on armv7emdp } else if (strcmp(arch, "armv7m") == 0) { mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV7M; mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_ARM_THUMB_FP; diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index d91e1d6d6e5d1..099c372fdddb6 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -1,7 +1,28 @@ -// SPDX-FileCopyrightText: Copyright (c) 2013-2015 Damien P. George -// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -// -// SPDX-License-Identifier: MIT +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2015 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ // options to control how MicroPython is built @@ -163,7 +184,7 @@ typedef long mp_off_t; #define MP_NOINLINE __declspec(noinline) #define MP_LIKELY(x) (x) #define MP_UNLIKELY(x) (x) -#define MICROPY_PORT_CONSTANTS { "dummy", 0 } +#define MICROPY_PORT_CONSTANTS { MP_ROM_QSTR(MP_QSTR_dummy), MP_ROM_PTR(NULL) } #ifdef _WIN64 #define MP_SSIZE_MAX _I64_MAX #else diff --git a/mpy-cross/mpy-cross.mk b/mpy-cross/mpy-cross.mk index 452e2f3c1f19e..db93f17123965 100644 --- a/mpy-cross/mpy-cross.mk +++ b/mpy-cross/mpy-cross.mk @@ -60,6 +60,8 @@ ifdef STATIC_BUILD LDFLAGS += -static -static-libgcc -static-libstdc++ endif +CFLAGS += -DCIRCUITPY=1 + # source files SRC_C += \ main.c \ @@ -78,6 +80,6 @@ endif OBJ = $(PY_CORE_O) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) -$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compression.generated.h +$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compressed_translations.generated.h include $(TOP)/py/mkrules.mk diff --git a/mpy-cross/mpy-cross.vcxproj b/mpy-cross/mpy-cross.vcxproj index e70b29ae14d7b..53cb0fa1fec71 100644 --- a/mpy-cross/mpy-cross.vcxproj +++ b/mpy-cross/mpy-cross.vcxproj @@ -1,5 +1,5 @@  - + Debug diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 4595998953124..0f01c789c6818 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -171,7 +171,10 @@ endif # we know is ok. It's not clear how to give the compiler the info it needs so # disable the checks for now. # See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99578 +GCCVERSIONGTEQ11 := $(shell expr `$(CC) -dumpversion` \>= 11) +ifeq ($(GCC_VERSION_GTEQ_11),1) CFLAGS += -Wno-stringop-overread -Wno-stringop-overflow +endif LDFLAGS = $(CFLAGS) -nostartfiles -Wl,-nostdlib -Wl,-T,$(GENERATED_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections -specs=nano.specs @@ -350,10 +353,12 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) SRC_QSTR += $(HEADER_BUILD)/sdiodata.h +OBJ_EXTRA_ORDER_DEPS += $(HEADER_BUILD)/sioddata.h $(HEADER_BUILD)/sdiodata.h: tools/mksdiodata.py | $(HEADER_BUILD) $(Q)$(PYTHON) $< > $@ SRC_QSTR += $(HEADER_BUILD)/candata.h +OBJ_EXTRA_ORDER_DEPS += $(HEADER_BUILD)/candata.h $(HEADER_BUILD)/candata.h: tools/mkcandata.py | $(HEADER_BUILD) $(Q)$(PYTHON) $< > $@ @@ -382,8 +387,3 @@ $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin $(Q)$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -b $(BOOTLOADER_SIZE) -c -o $@ $^ include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/atmel-samd/bindings/samd/__init__.c b/ports/atmel-samd/bindings/samd/__init__.c index 29d12357d1e43..8f36452926af0 100644 --- a/ports/atmel-samd/bindings/samd/__init__.c +++ b/ports/atmel-samd/bindings/samd/__init__.c @@ -57,4 +57,4 @@ const mp_obj_module_t samd_module = { .globals = (mp_obj_dict_t *)&samd_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_samd, samd_module, CIRCUITPY_SAMD); +MP_REGISTER_MODULE(MP_QSTR_samd, samd_module); diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/pins.c b/ports/atmel-samd/boards/circuitbrains_basic_m0/pins.c index ee2b947077993..0ecaf555ebd32 100644 --- a/ports/atmel-samd/boards/circuitbrains_basic_m0/pins.c +++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/pins.c @@ -22,15 +22,15 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA15) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED), MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PA04) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PA05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PA04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PA05) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA11) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA10) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA10) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA09) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c old mode 100755 new mode 100644 index 55001af5f787f..69f7ca050a969 --- a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c +++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/pins.c @@ -39,8 +39,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB14) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED),MP_ROM_PTR(&pin_PB13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_STATUS_LED), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB13) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB12) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PB31) }, @@ -48,12 +48,12 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PB23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PB22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/atmel-samd/boards/datalore_ip_m4/pins.c b/ports/atmel-samd/boards/datalore_ip_m4/pins.c index 8e52b20769519..bd922755dc4be 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/pins.c +++ b/ports/atmel-samd/boards/datalore_ip_m4/pins.c @@ -28,19 +28,19 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PA27) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/matrixportal_m4/pins.c b/ports/atmel-samd/boards/matrixportal_m4/pins.c index 205cd6f3c65da..05c2aeb13432e 100644 --- a/ports/atmel-samd/boards/matrixportal_m4/pins.c +++ b/ports/atmel-samd/boards/matrixportal_m4/pins.c @@ -9,8 +9,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA06) }, { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA07) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TX),MP_ROM_PTR(&pin_PA00) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RX),MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA01) }, // ESP control { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PB17) }, @@ -21,41 +21,41 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_PA13) }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB30) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB31) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB31) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PA23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA23) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA19) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA17) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA17) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R1),MP_ROM_PTR(&pin_PB00) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G1),MP_ROM_PTR(&pin_PB01) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B1),MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R1), MP_ROM_PTR(&pin_PB00) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G1), MP_ROM_PTR(&pin_PB01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B1), MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R2),MP_ROM_PTR(&pin_PB03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G2),MP_ROM_PTR(&pin_PB04) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B2),MP_ROM_PTR(&pin_PB05) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R2), MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G2), MP_ROM_PTR(&pin_PB04) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B2), MP_ROM_PTR(&pin_PB05) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRA),MP_ROM_PTR(&pin_PB07) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRB),MP_ROM_PTR(&pin_PB08) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRC),MP_ROM_PTR(&pin_PB09) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRD),MP_ROM_PTR(&pin_PB15) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRE),MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRA), MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRB), MP_ROM_PTR(&pin_PB08) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRC), MP_ROM_PTR(&pin_PB09) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRD), MP_ROM_PTR(&pin_PB15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRE), MP_ROM_PTR(&pin_PB13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_CLK),MP_ROM_PTR(&pin_PB06) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_LAT),MP_ROM_PTR(&pin_PB14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_OE),MP_ROM_PTR(&pin_PB12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_CLK), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_LAT), MP_ROM_PTR(&pin_PB14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_OE), MP_ROM_PTR(&pin_PB12) }, { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_PA27) }, // Grounded when closed. - { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_UP),MP_ROM_PTR(&pin_PB22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_DOWN),MP_ROM_PTR(&pin_PB23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_UP), MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_DOWN), MP_ROM_PTR(&pin_PB23) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_L),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PA14) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/pins.c b/ports/atmel-samd/boards/metro_m4_airlift_lite/pins.c index dcb6774da8503..5c496aa63be1a 100644 --- a/ports/atmel-samd/boards/metro_m4_airlift_lite/pins.c +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/pins.c @@ -29,8 +29,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA16) }, // ESP control { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PA15) }, @@ -41,17 +41,17 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_PA04) }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PA07) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PB07) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/metro_m4_express/pins.c b/ports/atmel-samd/boards/metro_m4_express/pins.c index 1f96885cc1e31..f7e50f645388c 100644 --- a/ports/atmel-samd/boards/metro_m4_express/pins.c +++ b/ports/atmel-samd/boards/metro_m4_express/pins.c @@ -29,20 +29,20 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA16) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PA27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PA27) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/picoplanet/pins.c b/ports/atmel-samd/boards/picoplanet/pins.c index 5a6abec10a820..1691063fc9ff5 100644 --- a/ports/atmel-samd/boards/picoplanet/pins.c +++ b/ports/atmel-samd/boards/picoplanet/pins.c @@ -7,15 +7,15 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA03) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA04) }, - { MP_ROM_QSTR(MP_QSTR_D5),MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_GREEN_LED),MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_GREEN_LED), MP_ROM_PTR(&pin_PA05) }, - { MP_ROM_QSTR(MP_QSTR_D6),MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_RED_LED),MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA06) }, - { MP_ROM_QSTR(MP_QSTR_D7),MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_BLUE_LED),MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA08) }, { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA08) }, diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index 1fa05cc460252..bdff2358ba3d4 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -29,7 +29,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PB23) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, // LCD pins { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA00) }, @@ -65,17 +65,17 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PB13) }, // SPI - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, // I2C - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, // SD Card - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_PB30) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT),MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_PA01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/atmel-samd/boards/pyportal_titano/pins.c b/ports/atmel-samd/boards/pyportal_titano/pins.c index 1fa05cc460252..bdff2358ba3d4 100644 --- a/ports/atmel-samd/boards/pyportal_titano/pins.c +++ b/ports/atmel-samd/boards/pyportal_titano/pins.c @@ -29,7 +29,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_PB23) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, // LCD pins { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_PA00) }, @@ -65,17 +65,17 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PB13) }, // SPI - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, // I2C - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, // SD Card - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_PB30) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT),MP_ROM_PTR(&pin_PA01) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PB30) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_PA01) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/atmel-samd/boards/pyruler/pins.c b/ports/atmel-samd/boards/pyruler/pins.c index 27583539f341b..a607af30f99ab 100644 --- a/ports/atmel-samd/boards/pyruler/pins.c +++ b/ports/atmel-samd/boards/pyruler/pins.c @@ -41,8 +41,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA10) }, - { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, diff --git a/ports/atmel-samd/boards/sam32/pins.c b/ports/atmel-samd/boards/sam32/pins.c index 68e4a13e95329..33abb0d7aaf23 100644 --- a/ports/atmel-samd/boards/sam32/pins.c +++ b/ports/atmel-samd/boards/sam32/pins.c @@ -13,7 +13,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB13) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB12) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB14) }, - { MP_ROM_QSTR(MP_QSTR_xSDCS),MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_xSDCS), MP_ROM_PTR(&pin_PA04) }, { MP_ROM_QSTR(MP_QSTR_DAC0), MP_ROM_PTR(&pin_PA02) }, { MP_ROM_QSTR(MP_QSTR_DAC1), MP_ROM_PTR(&pin_PA05) }, @@ -43,7 +43,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_TCK), MP_ROM_PTR(&pin_PB01) }, { MP_ROM_QSTR(MP_QSTR_TDI), MP_ROM_PTR(&pin_PB02) }, { MP_ROM_QSTR(MP_QSTR_TMS), MP_ROM_PTR(&pin_PB03) }, - { MP_ROM_QSTR(MP_QSTR_ESP_CS),MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PB15) }, { MP_ROM_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_PA12) }, { MP_ROM_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_PA13) }, diff --git a/ports/atmel-samd/boards/trinket_m0/pins.c b/ports/atmel-samd/boards/trinket_m0/pins.c index f9db8ff9946a8..1c93f935e339e 100644 --- a/ports/atmel-samd/boards/trinket_m0/pins.c +++ b/ports/atmel-samd/boards/trinket_m0/pins.c @@ -25,8 +25,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA10) }, - { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c index f9db8ff9946a8..1c93f935e339e 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/pins.c @@ -25,8 +25,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA07) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA07) }, - { MP_ROM_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA10) }, - { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA10) }, { MP_ROM_QSTR(MP_QSTR_APA102_MOSI), MP_ROM_PTR(&pin_PA00) }, { MP_ROM_QSTR(MP_QSTR_DOTSTAR_DATA), MP_ROM_PTR(&pin_PA00) }, diff --git a/ports/atmel-samd/boards/uartlogger2/pins.c b/ports/atmel-samd/boards/uartlogger2/pins.c index 4af8871ff0ebd..4dc3ee6e4f29e 100644 --- a/ports/atmel-samd/boards/uartlogger2/pins.c +++ b/ports/atmel-samd/boards/uartlogger2/pins.c @@ -28,7 +28,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA16) }, // ESP control { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_PA15) }, @@ -39,17 +39,17 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_PA04) }, { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_PA07) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_PB03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB02) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_PB22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK),MP_ROM_PTR(&pin_PA13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_PA12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_PA14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PA12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA14) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX),MP_ROM_PTR(&pin_PB06) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX),MP_ROM_PTR(&pin_PB07) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_RX), MP_ROM_PTR(&pin_PB06) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED_TX), MP_ROM_PTR(&pin_PB07) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/atmel-samd/boards/winterbloom_big_honking_button/usermods/_bhb/bhb.c b/ports/atmel-samd/boards/winterbloom_big_honking_button/usermods/_bhb/bhb.c index 1a340ae226789..8feca3181747b 100644 --- a/ports/atmel-samd/boards/winterbloom_big_honking_button/usermods/_bhb/bhb.c +++ b/ports/atmel-samd/boards/winterbloom_big_honking_button/usermods/_bhb/bhb.c @@ -127,4 +127,4 @@ const mp_obj_module_t _bhb_user_cmodule = { .globals = (mp_obj_dict_t *)&_bhb_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR__bhb, _bhb_user_cmodule, MODULE_BHB_ENABLED); +MP_REGISTER_MODULE(MP_QSTR__bhb, _bhb_user_cmodule); diff --git a/ports/atmel-samd/common-hal/alarm/__init__.c b/ports/atmel-samd/common-hal/alarm/__init__.c index 96d6d9694a607..f71e3c1806aa6 100644 --- a/ports/atmel-samd/common-hal/alarm/__init__.c +++ b/ports/atmel-samd/common-hal/alarm/__init__.c @@ -113,11 +113,11 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj RUN_BACKGROUND_TASKS; // Detect if interrupt was alarm or ctrl-C interrupt. if (alarm_time_timealarm_woke_this_cycle()) { - wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms, alarms); break; } if (alarm_pin_pinalarm_woke_this_cycle()) { - wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms, alarms); break; } diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index 92dbc9757eccb..36c7f020bc02d 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -222,14 +222,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (NULL != receiver_buffer) { self->buffer = receiver_buffer; } else { - // Initially allocate the UART's buffer in the long-lived part of the - // heap. UARTs are generally long-lived objects, but the "make long- - // lived" machinery is incapable of moving internal pointers like - // self->buffer, so do it manually. (However, as long as internal - // pointers like this are NOT moved, allocating the buffer - // in the long-lived pool is not strictly necessary) - - self->buffer = (uint8_t *)gc_alloc(self->buffer_length * sizeof(uint8_t), false, true); + self->buffer = (uint8_t *)gc_alloc(self->buffer_length * sizeof(uint8_t), false); if (self->buffer == NULL) { common_hal_busio_uart_deinit(self); m_malloc_fail(self->buffer_length * sizeof(uint8_t)); diff --git a/ports/atmel-samd/common-hal/canio/Listener.c b/ports/atmel-samd/common-hal/canio/Listener.c index 5cdfafe9c0395..28e82d7818655 100644 --- a/ports/atmel-samd/common-hal/canio/Listener.c +++ b/ports/atmel-samd/common-hal/canio/Listener.c @@ -368,8 +368,8 @@ mp_obj_t common_hal_canio_listener_receive(canio_listener_obj_t *self) { int index = self->hw->RXFS.bit.F0GI; canio_can_rx_fifo_t *hw_message = &self->fifo[index]; bool rtr = hw_message->rxf0.bit.RTR; - canio_message_obj_t *message = m_new_obj(canio_message_obj_t); - message->base.type = rtr ? &canio_remote_transmission_request_type : &canio_message_type; + canio_message_obj_t *message = + mp_obj_malloc(canio_message_obj_t, rtr ? &canio_remote_transmission_request_type : &canio_message_type); message->extended = hw_message->rxf0.bit.XTD; if (message->extended) { message->id = hw_message->rxf0.bit.ID; diff --git a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c index dc770a2de383a..5e8381e337ace 100644 --- a/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +++ b/ports/atmel-samd/common-hal/digitalio/DigitalInOut.c @@ -112,7 +112,7 @@ void common_hal_digitalio_digitalinout_set_value( } } else { hri_port_set_DIR_DIR_bf(PORT, port, pin_mask); - hri_port_clear_OUT_OUT_bf(PORT,port, pin_mask); + hri_port_clear_OUT_OUT_bf(PORT, port, pin_mask); } } diff --git a/ports/atmel-samd/common-hal/neopixel_write/__init__.c b/ports/atmel-samd/common-hal/neopixel_write/__init__.c index ac9a804333516..3520037afed4d 100644 --- a/ports/atmel-samd/common-hal/neopixel_write/__init__.c +++ b/ports/atmel-samd/common-hal/neopixel_write/__init__.c @@ -42,7 +42,7 @@ #include "hri/hri_nvmctrl_d51.h" #endif -__attribute__((naked,noinline,aligned(16))) +__attribute__((naked, noinline, aligned(16))) static void neopixel_send_buffer_core(volatile uint32_t *clraddr, uint32_t pinMask, const uint8_t *ptr, int numBytes); diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index 8bf889bed3c75..cc2c1f4fe0bc3 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -159,7 +159,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, mp_raise_RuntimeError(translate("EXTINT channel already in use")); } - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); + self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } diff --git a/ports/broadcom/Makefile b/ports/broadcom/Makefile index 9af0503fbbd44..bbafa2675111d 100644 --- a/ports/broadcom/Makefile +++ b/ports/broadcom/Makefile @@ -172,9 +172,3 @@ $(BUILD)/firmware.disk.img.zip: $(BUILD)/kernel$(SUFFIX).img $(Q)rm $(BUILD)/circuitpython-disk.img include $(TOP)/py/mkrules.mk - - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/broadcom/bindings/videocore/__init__.c b/ports/broadcom/bindings/videocore/__init__.c index 9ec345dae7040..ffb90680ef12e 100644 --- a/ports/broadcom/bindings/videocore/__init__.c +++ b/ports/broadcom/bindings/videocore/__init__.c @@ -45,4 +45,4 @@ const mp_obj_module_t videocore_module = { .globals = (mp_obj_dict_t *)&videocore_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_videocore, videocore_module, CIRCUITPY_VIDEOCORE); +MP_REGISTER_MODULE(MP_QSTR_videocore, videocore_module); diff --git a/ports/broadcom/boards/diodes_delight_piunora/pins.c b/ports/broadcom/boards/diodes_delight_piunora/pins.c index c1098d14120eb..a6907d398540a 100644 --- a/ports/broadcom/boards/diodes_delight_piunora/pins.c +++ b/ports/broadcom/boards/diodes_delight_piunora/pins.c @@ -27,40 +27,40 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_GPIO22), MP_ROM_PTR(&pin_GPIO22) }, { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO22) }, - { MP_ROM_QSTR(MP_QSTR_SDA6),MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SDA6), MP_ROM_PTR(&pin_GPIO22) }, { MP_ROM_QSTR(MP_QSTR_GPIO23), MP_ROM_PTR(&pin_GPIO23) }, { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO23) }, - { MP_ROM_QSTR(MP_QSTR_SCL6),MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SCL6), MP_ROM_PTR(&pin_GPIO23) }, { MP_ROM_QSTR(MP_QSTR_GPIO6), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_SDA4),MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SDA4), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_GPIO7), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO7) }, - { MP_ROM_QSTR(MP_QSTR_SCL4),MP_ROM_PTR(&pin_GPIO7) }, - { MP_ROM_QSTR(MP_QSTR_SPI0_CE1),MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SCL4), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_CE1), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_GPIO8), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_SPI0_CE0),MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_CE0), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_GPIO10), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO10) }, - { MP_ROM_QSTR(MP_QSTR_SPI0_MOSI),MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_MOSI), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_GPIO9), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_SPI0_MISO),MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_MISO), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_GPIO11), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_SPI0_SCLK),MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_SCLK), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_SDA1),MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, { MP_ROM_QSTR(MP_QSTR_GPIO12), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO12) }, diff --git a/ports/broadcom/common-hal/busio/UART.c b/ports/broadcom/common-hal/busio/UART.c index 0eb72b1456b0e..c6888f93303a3 100644 --- a/ports/broadcom/common-hal/busio/UART.c +++ b/ports/broadcom/common-hal/busio/UART.c @@ -212,13 +212,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (receiver_buffer != NULL) { ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { - // Initially allocate the UART's buffer in the long-lived part of the - // heap. UARTs are generally long-lived objects, but the "make long- - // lived" machinery is incapable of moving internal pointers like - // self->buffer, so do it manually. (However, as long as internal - // pointers like this are NOT moved, allocating the buffer - // in the long-lived pool is not strictly necessary) - if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size)) { m_malloc_fail(receiver_buffer_size); } } diff --git a/ports/cxd56/Makefile b/ports/cxd56/Makefile index 35a4df1393407..9ec889e2570e6 100644 --- a/ports/cxd56/Makefile +++ b/ports/cxd56/Makefile @@ -198,8 +198,3 @@ flash-bootloader: $(SPRESENSE_SDK) $(FIRMWARE) tools/flash_writer.py -s -c $(SERIAL) -d -b 115200 -n $(BOOTLOADER_FILES) include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/cxd56/common-hal/pulseio/PulseIn.c b/ports/cxd56/common-hal/pulseio/PulseIn.c index 165e2a6ece23a..989acd491cf72 100644 --- a/ports/cxd56/common-hal/pulseio/PulseIn.c +++ b/ports/cxd56/common-hal/pulseio/PulseIn.c @@ -85,7 +85,7 @@ static int pulsein_interrupt_handler(int irq, FAR void *context, FAR void *arg) void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); + self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } diff --git a/ports/cxd56/mkspk/elf32.h b/ports/cxd56/mkspk/elf32.h index e19ce210a66b6..96cb51c195198 100644 --- a/ports/cxd56/mkspk/elf32.h +++ b/ports/cxd56/mkspk/elf32.h @@ -53,13 +53,13 @@ #define ELF32_ST_BIND(i) ((i) >> 4) #define ELF32_ST_TYPE(i) ((i) & 0xf) -#define ELF32_ST_INFO(b,t) (((b) << 4) | ((t) & 0xf)) +#define ELF32_ST_INFO(b, t) (((b) << 4) | ((t) & 0xf)) /* Definitions for Elf32_Rel*::r_info */ #define ELF32_R_SYM(i) ((i) >> 8) #define ELF32_R_TYPE(i) ((i) & 0xff) -#define ELF32_R_INFO(s,t) (((s) << 8) | ((t) & 0xff)) +#define ELF32_R_INFO(s, t) (((s) << 8) | ((t) & 0xff)) #define ELF_R_SYM(i) ELF32_R_SYM(i) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index b1bfa4f8c7e2a..a335115f0ffe2 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -353,6 +353,7 @@ endif # create the config headers .PHONY: do-sdkconfig do-sdkconfig: $(BUILD)/esp-idf/config/sdkconfig.h +Makefile: $(BUILD)/esp-idf/config/sdkconfig.h $(BUILD)/esp-idf/config/sdkconfig.h: boards/$(BOARD)/sdkconfig CMakeLists.txt | $(BUILD)/esp-idf IDF_PATH=$(IDF_PATH) cmake -S . -B $(BUILD)/esp-idf -DSDKCONFIG=$(BUILD)/esp-idf/sdkconfig -DSDKCONFIG_DEFAULTS="$(SDKCONFIGS)" -DCMAKE_TOOLCHAIN_FILE=$(IDF_PATH)/tools/cmake/toolchain-$(IDF_TARGET).cmake -DIDF_TARGET=$(IDF_TARGET) -GNinja -DCIRCUITPY_ESPCAMERA=$(CIRCUITPY_ESPCAMERA) @@ -486,8 +487,3 @@ monitor: $(BUILD)/firmware.elf idf.py monitor -p $(PORT) include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/espressif/bindings/espcamera/Camera.c b/ports/espressif/bindings/espcamera/Camera.c index 5fb9576e58869..109ed5cffe634 100644 --- a/ports/espressif/bindings/espcamera/Camera.c +++ b/ports/espressif/bindings/espcamera/Camera.c @@ -143,8 +143,7 @@ STATIC mp_obj_t espcamera_camera_make_new(const mp_obj_type_t *type, size_t n_ar mp_int_t jpeg_quality = mp_arg_validate_int_range(args[ARG_jpeg_quality].u_int, 2, 55, MP_QSTR_jpeg_quality); mp_int_t framebuffer_count = mp_arg_validate_int_range(args[ARG_framebuffer_count].u_int, 1, 2, MP_QSTR_framebuffer_count); - espcamera_camera_obj_t *self = m_new_obj(espcamera_camera_obj_t); - self->base.type = &espcamera_camera_type; + espcamera_camera_obj_t *self = mp_obj_malloc(espcamera_camera_obj_t, &espcamera_camera_type); common_hal_espcamera_camera_construct( self, data_pins, diff --git a/ports/espressif/bindings/espcamera/__init__.c b/ports/espressif/bindings/espcamera/__init__.c index 633f547fe912e..3963f46bfeb94 100644 --- a/ports/espressif/bindings/espcamera/__init__.c +++ b/ports/espressif/bindings/espcamera/__init__.c @@ -285,4 +285,4 @@ const mp_obj_module_t espcamera_module = { .globals = (mp_obj_dict_t *)&espcamera_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_espcamera, espcamera_module, CIRCUITPY_ESPCAMERA); +MP_REGISTER_MODULE(MP_QSTR_espcamera, espcamera_module); diff --git a/ports/espressif/bindings/espnow/ESPNow.c b/ports/espressif/bindings/espnow/ESPNow.c index 78d80924fdd60..6255e19f8698b 100644 --- a/ports/espressif/bindings/espnow/ESPNow.c +++ b/ports/espressif/bindings/espnow/ESPNow.c @@ -78,8 +78,7 @@ STATIC mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args, size_t } // Allocate a new object - self = m_new_obj(espnow_obj_t); - self->base.type = &espnow_type; + self = mp_obj_malloc(espnow_obj_t, &espnow_type); // Construct the object common_hal_espnow_construct(self, args[ARG_buffer_size].u_int, args[ARG_phy_rate].u_int); @@ -284,29 +283,29 @@ MP_PROPERTY_GETTER(espnow_peers_obj, STATIC const mp_rom_map_elem_t espnow_locals_dict_table[] = { // Context managers - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espnow___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espnow___exit___obj) }, // Deinit the object - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espnow_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espnow_deinit_obj) }, // Send messages - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&espnow_send_obj) }, - { MP_ROM_QSTR(MP_QSTR_send_success),MP_ROM_PTR(&espnow_send_success_obj)}, - { MP_ROM_QSTR(MP_QSTR_send_failure),MP_ROM_PTR(&espnow_send_failure_obj)}, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&espnow_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_send_success), MP_ROM_PTR(&espnow_send_success_obj)}, + { MP_ROM_QSTR(MP_QSTR_send_failure), MP_ROM_PTR(&espnow_send_failure_obj)}, // Read messages - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&espnow_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_read_success),MP_ROM_PTR(&espnow_read_success_obj)}, - { MP_ROM_QSTR(MP_QSTR_read_failure),MP_ROM_PTR(&espnow_read_failure_obj)}, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&espnow_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_success), MP_ROM_PTR(&espnow_read_success_obj)}, + { MP_ROM_QSTR(MP_QSTR_read_failure), MP_ROM_PTR(&espnow_read_failure_obj)}, // Config parameters - { MP_ROM_QSTR(MP_QSTR_set_pmk), MP_ROM_PTR(&espnow_set_pmk_obj) }, - { MP_ROM_QSTR(MP_QSTR_buffer_size), MP_ROM_PTR(&espnow_buffer_size_obj) }, - { MP_ROM_QSTR(MP_QSTR_phy_rate), MP_ROM_PTR(&espnow_phy_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_pmk), MP_ROM_PTR(&espnow_set_pmk_obj) }, + { MP_ROM_QSTR(MP_QSTR_buffer_size), MP_ROM_PTR(&espnow_buffer_size_obj) }, + { MP_ROM_QSTR(MP_QSTR_phy_rate), MP_ROM_PTR(&espnow_phy_rate_obj) }, // Peer related properties - { MP_ROM_QSTR(MP_QSTR_peers), MP_ROM_PTR(&espnow_peers_obj) }, + { MP_ROM_QSTR(MP_QSTR_peers), MP_ROM_PTR(&espnow_peers_obj) }, }; STATIC MP_DEFINE_CONST_DICT(espnow_locals_dict, espnow_locals_dict_table); diff --git a/ports/espressif/bindings/espnow/Peer.c b/ports/espressif/bindings/espnow/Peer.c index f69bec01e6a5f..4cceec1498428 100644 --- a/ports/espressif/bindings/espnow/Peer.c +++ b/ports/espressif/bindings/espnow/Peer.c @@ -55,18 +55,17 @@ STATIC mp_obj_t espnow_peer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_mac, ARG_lmk, ARG_channel, ARG_interface, ARG_encrypted }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_mac, MP_ARG_OBJ | MP_ARG_REQUIRED }, - { MP_QSTR_lmk, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } }, - { MP_QSTR_channel, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, - { MP_QSTR_interface,MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, - { MP_QSTR_encrypted,MP_ARG_BOOL | MP_ARG_KW_ONLY,{ .u_bool = false } }, + { MP_QSTR_mac, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_lmk, MP_ARG_OBJ | MP_ARG_KW_ONLY, { .u_obj = mp_const_none } }, + { MP_QSTR_channel, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, + { MP_QSTR_interface, MP_ARG_INT | MP_ARG_KW_ONLY, { .u_int = 0 } }, + { MP_QSTR_encrypted, MP_ARG_BOOL | MP_ARG_KW_ONLY, { .u_bool = false } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - espnow_peer_obj_t *self = m_new_obj(espnow_peer_obj_t); - self->base.type = &espnow_peer_type; + espnow_peer_obj_t *self = mp_obj_malloc(espnow_peer_obj_t, &espnow_peer_type); self->peer_info = (esp_now_peer_info_t) { .channel = 0, .ifidx = WIFI_IF_STA, diff --git a/ports/espressif/bindings/espnow/Peers.c b/ports/espressif/bindings/espnow/Peers.c index 6fda9aed7a5e0..096a5266a05d4 100644 --- a/ports/espressif/bindings/espnow/Peers.c +++ b/ports/espressif/bindings/espnow/Peers.c @@ -118,8 +118,7 @@ STATIC mp_obj_t espnow_peers_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_b } espnow_peers_obj_t *espnow_peers_new(void) { - espnow_peers_obj_t *self = m_new_obj(espnow_peers_obj_t); - self->base.type = &espnow_peers_type; + espnow_peers_obj_t *self = mp_obj_malloc(espnow_peers_obj_t, &espnow_peers_type); self->list = mp_obj_new_list(0, NULL); return self; } diff --git a/ports/espressif/bindings/espnow/__init__.c b/ports/espressif/bindings/espnow/__init__.c index 31358586012fe..e44cd6b11f1ab 100644 --- a/ports/espressif/bindings/espnow/__init__.c +++ b/ports/espressif/bindings/espnow/__init__.c @@ -80,7 +80,7 @@ STATIC const mp_rom_map_elem_t espnow_module_globals_table[] = { // module classes { MP_ROM_QSTR(MP_QSTR_ESPNow), MP_ROM_PTR(&espnow_type) }, - { MP_ROM_QSTR(MP_QSTR_ESPNowPacket),MP_ROM_PTR(&espnow_packet_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_ESPNowPacket), MP_ROM_PTR(&espnow_packet_type_obj) }, { MP_ROM_QSTR(MP_QSTR_Peer), MP_ROM_PTR(&espnow_peer_type) }, { MP_ROM_QSTR(MP_QSTR_Peers), MP_ROM_PTR(&espnow_peers_type) }, }; @@ -91,4 +91,4 @@ const mp_obj_module_t espnow_module = { .globals = (mp_obj_dict_t *)&espnow_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_espnow, espnow_module, CIRCUITPY_ESPNOW); +MP_REGISTER_MODULE(MP_QSTR_espnow, espnow_module); diff --git a/ports/espressif/bindings/espulp/ULP.c b/ports/espressif/bindings/espulp/ULP.c index c9666fb1435b2..09453c9a09182 100644 --- a/ports/espressif/bindings/espulp/ULP.c +++ b/ports/espressif/bindings/espulp/ULP.c @@ -52,8 +52,7 @@ STATIC mp_obj_t espulp_ulp_make_new(const mp_obj_type_t *type, size_t n_args, si const espulp_architecture_t arch = cp_enum_value(&espulp_architecture_type, args[ARG_arch].u_obj, MP_QSTR_arch); - espulp_ulp_obj_t *self = m_new_obj(espulp_ulp_obj_t); - self->base.type = &espulp_ulp_type; + espulp_ulp_obj_t *self = mp_obj_malloc(espulp_ulp_obj_t, &espulp_ulp_type); common_hal_espulp_ulp_construct(self, arch); diff --git a/ports/espressif/bindings/espulp/ULPAlarm.c b/ports/espressif/bindings/espulp/ULPAlarm.c index 6efd1c98ef554..b8b0a7c1229d0 100644 --- a/ports/espressif/bindings/espulp/ULPAlarm.c +++ b/ports/espressif/bindings/espulp/ULPAlarm.c @@ -50,8 +50,7 @@ STATIC mp_obj_t espulp_ulpalarm_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - espulp_ulpalarm_obj_t *self = m_new_obj(espulp_ulpalarm_obj_t); - self->base.type = &espulp_ulpalarm_type; + espulp_ulpalarm_obj_t *self = mp_obj_malloc(espulp_ulpalarm_obj_t, &espulp_ulpalarm_type); espulp_ulp_obj_t *ulp = mp_arg_validate_type(args[ARG_ulp].u_obj, &espulp_ulp_type, MP_QSTR_ulp); diff --git a/ports/espressif/bindings/espulp/__init__.c b/ports/espressif/bindings/espulp/__init__.c index f2b688dda4f0f..36f50e8949ff0 100644 --- a/ports/espressif/bindings/espulp/__init__.c +++ b/ports/espressif/bindings/espulp/__init__.c @@ -91,4 +91,4 @@ const mp_obj_module_t espulp_module = { .globals = (mp_obj_dict_t *)&espulp_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_espulp, espulp_module, CIRCUITPY_ESPULP); +MP_REGISTER_MODULE(MP_QSTR_espulp, espulp_module); diff --git a/ports/espressif/boards/adafruit_matrixportal_s3/pins.c b/ports/espressif/boards/adafruit_matrixportal_s3/pins.c index 5cdd9ab92c7c9..3485bf0b68660 100644 --- a/ports/espressif/boards/adafruit_matrixportal_s3/pins.c +++ b/ports/espressif/boards/adafruit_matrixportal_s3/pins.c @@ -28,10 +28,10 @@ STATIC const mp_rom_obj_tuple_t matrix_data_tuple = { }; STATIC const mp_rom_map_elem_t matrix_common_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_rgb_pins),MP_ROM_PTR(&matrix_data_tuple) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_clock_pin),MP_ROM_PTR(&pin_GPIO2) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_latch_pin),MP_ROM_PTR(&pin_GPIO47) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_output_enable_pin),MP_ROM_PTR(&pin_GPIO14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_rgb_pins), MP_ROM_PTR(&matrix_data_tuple) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_clock_pin), MP_ROM_PTR(&pin_GPIO2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_latch_pin), MP_ROM_PTR(&pin_GPIO47) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_output_enable_pin), MP_ROM_PTR(&pin_GPIO14) }, }; MP_DEFINE_CONST_DICT(matrix_common_dict, matrix_common_table); @@ -66,32 +66,32 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRESS),MP_ROM_PTR(&matrix_addr_tuple) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_COMMON),MP_ROM_PTR(&matrix_common_dict) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRESS), MP_ROM_PTR(&matrix_addr_tuple) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_COMMON), MP_ROM_PTR(&matrix_common_dict) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R1),MP_ROM_PTR(&pin_GPIO42) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G1),MP_ROM_PTR(&pin_GPIO41) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B1),MP_ROM_PTR(&pin_GPIO40) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R1), MP_ROM_PTR(&pin_GPIO42) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G1), MP_ROM_PTR(&pin_GPIO41) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B1), MP_ROM_PTR(&pin_GPIO40) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R2),MP_ROM_PTR(&pin_GPIO38) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G2),MP_ROM_PTR(&pin_GPIO39) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B2),MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_R2), MP_ROM_PTR(&pin_GPIO38) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_G2), MP_ROM_PTR(&pin_GPIO39) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_B2), MP_ROM_PTR(&pin_GPIO37) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRA),MP_ROM_PTR(&pin_GPIO45) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRB),MP_ROM_PTR(&pin_GPIO36) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRC),MP_ROM_PTR(&pin_GPIO48) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRD),MP_ROM_PTR(&pin_GPIO35) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRE),MP_ROM_PTR(&pin_GPIO21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRA), MP_ROM_PTR(&pin_GPIO45) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRB), MP_ROM_PTR(&pin_GPIO36) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRC), MP_ROM_PTR(&pin_GPIO48) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRD), MP_ROM_PTR(&pin_GPIO35) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_ADDRE), MP_ROM_PTR(&pin_GPIO21) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_CLK),MP_ROM_PTR(&pin_GPIO2) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_LAT),MP_ROM_PTR(&pin_GPIO47) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_OE),MP_ROM_PTR(&pin_GPIO14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_CLK), MP_ROM_PTR(&pin_GPIO2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_LAT), MP_ROM_PTR(&pin_GPIO47) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MTX_OE), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_ACCELEROMETER_INTERRUPT), MP_ROM_PTR(&pin_GPIO15) }, // Grounded when closed. - { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_UP),MP_ROM_PTR(&pin_GPIO6) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_DOWN),MP_ROM_PTR(&pin_GPIO7) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_UP), MP_ROM_PTR(&pin_GPIO6) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON_DOWN), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/espressif/boards/adafruit_metro_esp32s2/pins.c b/ports/espressif/boards/adafruit_metro_esp32s2/pins.c index 1f024f6e8ef97..39b47466d0689 100644 --- a/ports/espressif/boards/adafruit_metro_esp32s2/pins.c +++ b/ports/espressif/boards/adafruit_metro_esp32s2/pins.c @@ -39,20 +39,20 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, { MP_OBJ_NEW_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_GPIO33) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO33),MP_ROM_PTR(&pin_GPIO33) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO33) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_GPIO34) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO34),MP_ROM_PTR(&pin_GPIO34) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO34) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, { MP_OBJ_NEW_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_GPIO35) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO35),MP_ROM_PTR(&pin_GPIO35) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_GPIO37) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO37),MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, { MP_OBJ_NEW_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO42) }, diff --git a/ports/espressif/boards/adafruit_metro_esp32s3/pins.c b/ports/espressif/boards/adafruit_metro_esp32s3/pins.c index 3e0f65d335a94..ccc9d6fc6f097 100644 --- a/ports/espressif/boards/adafruit_metro_esp32s3/pins.c +++ b/ports/espressif/boards/adafruit_metro_esp32s3/pins.c @@ -66,22 +66,22 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_GPIO47) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO47),MP_ROM_PTR(&pin_GPIO47) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_GPIO48) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO48),MP_ROM_PTR(&pin_GPIO48) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO48) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_GPIO21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO21) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, { MP_OBJ_NEW_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI),MP_ROM_PTR(&pin_GPIO35) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO35),MP_ROM_PTR(&pin_GPIO35) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO),MP_ROM_PTR(&pin_GPIO37) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_IO37),MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO45) }, { MP_OBJ_NEW_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, diff --git a/ports/espressif/boards/m5stack_core2/board.c b/ports/espressif/boards/m5stack_core2/board.c index 5080617df43ea..e64ac35a7ddc6 100644 --- a/ports/espressif/boards/m5stack_core2/board.c +++ b/ports/espressif/boards/m5stack_core2/board.c @@ -48,21 +48,21 @@ displayio_fourwire_obj_t board_display_obj; // display init sequence according to M5Gfx uint8_t display_init_sequence[] = { - 0x01,DELAY,0x80, // Software reset then delay 0x80 (128ms) - 0xC8,0x03,0xFF,0x93,0x42, // Turn on the external command - 0xC0,0x02,0x12, 0x12, // Power Control 1 - 0xC1,0x01,0x03, // Power Control 2 - 0xC5,0x01,0xF2, // VCOM Control 1 - 0xB0,0x01,0xE0, // RGB Interface SYNC Mode - 0xF6,0x03,0x01, 0x00, 0x00, // Interface control - 0XE0,0x0F,0x00,0x0C,0x11,0x04,0x11,0x08,0x37,0x89,0x4C,0x06,0x0C,0x0A,0x2E,0x34,0x0F, // Positive Gamma Correction - 0xE1,0x0F,0x00,0x0B,0x11,0x05,0x13,0x09,0x33,0x67,0x48,0x07,0x0E,0x0B,0x2E,0x33,0x0F, // Negative Gamma Correction - 0xB6,0x04,0x08,0x82,0x1D,0x04, // Display Function Control - 0x3A,0x01,0x55, // COLMOD: Pixel Format Set 16 bit - 0x21,0x00, // Display inversion ON - 0x36,0x01,0x08, // Memory Access Control: RGB order - 0x11,DELAY,0x78, // Exit Sleep then delay 0x78 (120ms) - 0x29,DELAY,0x78, // Display on then delay 0x78 (120ms) + 0x01, DELAY, 0x80, // Software reset then delay 0x80 (128ms) + 0xC8, 0x03, 0xFF, 0x93, 0x42, // Turn on the external command + 0xC0, 0x02, 0x12, 0x12, // Power Control 1 + 0xC1, 0x01, 0x03, // Power Control 2 + 0xC5, 0x01, 0xF2, // VCOM Control 1 + 0xB0, 0x01, 0xE0, // RGB Interface SYNC Mode + 0xF6, 0x03, 0x01, 0x00, 0x00, // Interface control + 0XE0, 0x0F, 0x00, 0x0C, 0x11, 0x04, 0x11, 0x08, 0x37, 0x89, 0x4C, 0x06, 0x0C, 0x0A, 0x2E, 0x34, 0x0F, // Positive Gamma Correction + 0xE1, 0x0F, 0x00, 0x0B, 0x11, 0x05, 0x13, 0x09, 0x33, 0x67, 0x48, 0x07, 0x0E, 0x0B, 0x2E, 0x33, 0x0F, // Negative Gamma Correction + 0xB6, 0x04, 0x08, 0x82, 0x1D, 0x04, // Display Function Control + 0x3A, 0x01, 0x55, // COLMOD: Pixel Format Set 16 bit + 0x21, 0x00, // Display inversion ON + 0x36, 0x01, 0x08, // Memory Access Control: RGB order + 0x11, DELAY, 0x78, // Exit Sleep then delay 0x78 (120ms) + 0x29, DELAY, 0x78, // Display on then delay 0x78 (120ms) }; static bool pmic_set_power_source(uint8_t source, busio_i2c_obj_t *i2c) { diff --git a/ports/espressif/boards/m5stack_core2/pins.c b/ports/espressif/boards/m5stack_core2/pins.c index ee8fe21ad911b..bc936655fe473 100644 --- a/ports/espressif/boards/m5stack_core2/pins.c +++ b/ports/espressif/boards/m5stack_core2/pins.c @@ -80,10 +80,10 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { // { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO32) }, AXP_DC3 // sd card - { MP_ROM_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO4) }, // touch screen - { MP_ROM_QSTR(MP_QSTR_TOUCH_INT),MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO39) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, diff --git a/ports/espressif/boards/m5stack_core_basic/board.c b/ports/espressif/boards/m5stack_core_basic/board.c index 68eff30782e61..270f3a64ede8e 100644 --- a/ports/espressif/boards/m5stack_core_basic/board.c +++ b/ports/espressif/boards/m5stack_core_basic/board.c @@ -38,21 +38,21 @@ displayio_fourwire_obj_t board_display_obj; // display init sequence according to M5Gfx uint8_t display_init_sequence[] = { - 0x01,0x80,0x80, // Software reset then delay 0x80 (128ms) - 0xC8,0x03,0xFF,0x93,0x42, // Turn on the external command - 0xC0,0x02,0x12, 0x12, // Power Control 1 - 0xC1,0x01,0x03, // Power Control 2 - 0xC5,0x01,0xF2, // VCOM Control 1 - 0xB0,0x01,0xE0, // RGB Interface SYNC Mode - 0xF6,0x03,0x01, 0x00, 0x00, // Interface control - 0XE0,0x0F,0x00,0x0C,0x11,0x04,0x11,0x08,0x37,0x89,0x4C,0x06,0x0C,0x0A,0x2E,0x34,0x0F, // Positive Gamma Correction - 0xE1,0x0F,0x00,0x0B,0x11,0x05,0x13,0x09,0x33,0x67,0x48,0x07,0x0E,0x0B,0x2E,0x33,0x0F, // Negative Gamma Correction - 0xB6,0x04,0x08,0x82,0x1D,0x04, // Display Function Control - 0x3A,0x01,0x55, // COLMOD: Pixel Format Set 16 bit - 0x21,0x00, // Display inversion ON - 0x36,0x01,0x08, // Memory Access Control: RGB order - 0x11,0x80,0x78, // Exit Sleep then delay 0x78 (120ms) - 0x29,0x80,0x78, // Display on then delay 0x78 (120ms) + 0x01, 0x80, 0x80, // Software reset then delay 0x80 (128ms) + 0xC8, 0x03, 0xFF, 0x93, 0x42, // Turn on the external command + 0xC0, 0x02, 0x12, 0x12, // Power Control 1 + 0xC1, 0x01, 0x03, // Power Control 2 + 0xC5, 0x01, 0xF2, // VCOM Control 1 + 0xB0, 0x01, 0xE0, // RGB Interface SYNC Mode + 0xF6, 0x03, 0x01, 0x00, 0x00, // Interface control + 0XE0, 0x0F, 0x00, 0x0C, 0x11, 0x04, 0x11, 0x08, 0x37, 0x89, 0x4C, 0x06, 0x0C, 0x0A, 0x2E, 0x34, 0x0F, // Positive Gamma Correction + 0xE1, 0x0F, 0x00, 0x0B, 0x11, 0x05, 0x13, 0x09, 0x33, 0x67, 0x48, 0x07, 0x0E, 0x0B, 0x2E, 0x33, 0x0F, // Negative Gamma Correction + 0xB6, 0x04, 0x08, 0x82, 0x1D, 0x04, // Display Function Control + 0x3A, 0x01, 0x55, // COLMOD: Pixel Format Set 16 bit + 0x21, 0x00, // Display inversion ON + 0x36, 0x01, 0x08, // Memory Access Control: RGB order + 0x11, 0x80, 0x78, // Exit Sleep then delay 0x78 (120ms) + 0x29, 0x80, 0x78, // Display on then delay 0x78 (120ms) }; void board_init(void) { diff --git a/ports/espressif/boards/m5stack_core_basic/pins.c b/ports/espressif/boards/m5stack_core_basic/pins.c index b985231bea841..b03ab55dbfefe 100644 --- a/ports/espressif/boards/m5stack_core_basic/pins.c +++ b/ports/espressif/boards/m5stack_core_basic/pins.c @@ -76,7 +76,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BTN_C), MP_ROM_PTR(&pin_GPIO37) }, // sd card - { MP_ROM_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO4) }, // tft { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO14) }, diff --git a/ports/espressif/boards/m5stack_core_fire/board.c b/ports/espressif/boards/m5stack_core_fire/board.c old mode 100755 new mode 100644 index 68eff30782e61..270f3a64ede8e --- a/ports/espressif/boards/m5stack_core_fire/board.c +++ b/ports/espressif/boards/m5stack_core_fire/board.c @@ -38,21 +38,21 @@ displayio_fourwire_obj_t board_display_obj; // display init sequence according to M5Gfx uint8_t display_init_sequence[] = { - 0x01,0x80,0x80, // Software reset then delay 0x80 (128ms) - 0xC8,0x03,0xFF,0x93,0x42, // Turn on the external command - 0xC0,0x02,0x12, 0x12, // Power Control 1 - 0xC1,0x01,0x03, // Power Control 2 - 0xC5,0x01,0xF2, // VCOM Control 1 - 0xB0,0x01,0xE0, // RGB Interface SYNC Mode - 0xF6,0x03,0x01, 0x00, 0x00, // Interface control - 0XE0,0x0F,0x00,0x0C,0x11,0x04,0x11,0x08,0x37,0x89,0x4C,0x06,0x0C,0x0A,0x2E,0x34,0x0F, // Positive Gamma Correction - 0xE1,0x0F,0x00,0x0B,0x11,0x05,0x13,0x09,0x33,0x67,0x48,0x07,0x0E,0x0B,0x2E,0x33,0x0F, // Negative Gamma Correction - 0xB6,0x04,0x08,0x82,0x1D,0x04, // Display Function Control - 0x3A,0x01,0x55, // COLMOD: Pixel Format Set 16 bit - 0x21,0x00, // Display inversion ON - 0x36,0x01,0x08, // Memory Access Control: RGB order - 0x11,0x80,0x78, // Exit Sleep then delay 0x78 (120ms) - 0x29,0x80,0x78, // Display on then delay 0x78 (120ms) + 0x01, 0x80, 0x80, // Software reset then delay 0x80 (128ms) + 0xC8, 0x03, 0xFF, 0x93, 0x42, // Turn on the external command + 0xC0, 0x02, 0x12, 0x12, // Power Control 1 + 0xC1, 0x01, 0x03, // Power Control 2 + 0xC5, 0x01, 0xF2, // VCOM Control 1 + 0xB0, 0x01, 0xE0, // RGB Interface SYNC Mode + 0xF6, 0x03, 0x01, 0x00, 0x00, // Interface control + 0XE0, 0x0F, 0x00, 0x0C, 0x11, 0x04, 0x11, 0x08, 0x37, 0x89, 0x4C, 0x06, 0x0C, 0x0A, 0x2E, 0x34, 0x0F, // Positive Gamma Correction + 0xE1, 0x0F, 0x00, 0x0B, 0x11, 0x05, 0x13, 0x09, 0x33, 0x67, 0x48, 0x07, 0x0E, 0x0B, 0x2E, 0x33, 0x0F, // Negative Gamma Correction + 0xB6, 0x04, 0x08, 0x82, 0x1D, 0x04, // Display Function Control + 0x3A, 0x01, 0x55, // COLMOD: Pixel Format Set 16 bit + 0x21, 0x00, // Display inversion ON + 0x36, 0x01, 0x08, // Memory Access Control: RGB order + 0x11, 0x80, 0x78, // Exit Sleep then delay 0x78 (120ms) + 0x29, 0x80, 0x78, // Display on then delay 0x78 (120ms) }; void board_init(void) { diff --git a/ports/espressif/boards/m5stack_core_fire/pins.c b/ports/espressif/boards/m5stack_core_fire/pins.c index f26f96ac8e4cb..6694e284d1735 100644 --- a/ports/espressif/boards/m5stack_core_fire/pins.c +++ b/ports/espressif/boards/m5stack_core_fire/pins.c @@ -78,7 +78,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BTN_C), MP_ROM_PTR(&pin_GPIO37) }, // sd card - { MP_ROM_QSTR(MP_QSTR_SD_CS),MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO4) }, // tft { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO14) }, diff --git a/ports/espressif/boards/m5stack_stick_c/board.c b/ports/espressif/boards/m5stack_stick_c/board.c old mode 100755 new mode 100644 index e6a0125fb4a0a..779125a017c0f --- a/ports/espressif/boards/m5stack_stick_c/board.c +++ b/ports/espressif/boards/m5stack_stick_c/board.c @@ -41,25 +41,25 @@ // display init sequence according to adafruit_st7735r.py library uint8_t display_init_sequence[] = { - 0x01,0x80,0x96, // SWRESET and Delay 150ms - 0x11,0x80,0xff, // SLPOUT and Delay - 0xb1,0x03,0x01,0x2C,0x2D, // _FRMCTR1 - 0xb2,0x03,0x01,0x2C,0x2D, // _FRMCTR2 - 0xb3,0x06,0x01,0x2C,0x2D,0x01,0x2C,0x2D, // _FRMCTR3 - 0xb4,0x01,0x07, // _INVCTR line inversion - 0xc0,0x03,0xa2,0x02,0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA - 0xc1,0x01,0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V - 0xc2,0x02,0x0a,0x00, // _PWCTR3 Opamp current small, Boost frequency - 0xc3,0x02,0x8a,0x2a, - 0xc4,0x02,0x8a,0xee, - 0xc5,0x01,0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V - 0x36,0x01,0xc8, // MADCTL Rotate display - 0x21,0x00, // _INVON - 0x3a,0x01,0x05, // COLMOD - 16bit color - 0xe0,0x10,0x02,0x1c,0x07,0x12,0x37,0x32,0x29,0x2d,0x29,0x25,0x2B,0x39,0x00,0x01,0x03,0x10, // _GMCTRP1 Gamma - 0xe1,0x10,0x03,0x1d,0x07,0x06,0x2E,0x2C,0x29,0x2D,0x2E,0x2E,0x37,0x3F,0x00,0x00,0x02,0x10, // _GMCTRN1 - 0x13,0x80,0x0a, // _NORON - 0x29,0x80,0x64 // _DISPON + 0x01, 0x80, 0x96, // SWRESET and Delay 150ms + 0x11, 0x80, 0xff, // SLPOUT and Delay + 0xb1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR2 + 0xb3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xb4, 0x01, 0x07, // _INVCTR line inversion + 0xc0, 0x03, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 0x01, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 0x02, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 0x02, 0x8a, 0x2a, + 0xc4, 0x02, 0x8a, 0xee, + 0xc5, 0x01, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x36, 0x01, 0xc8, // MADCTL Rotate display + 0x21, 0x00, // _INVON + 0x3a, 0x01, 0x05, // COLMOD - 16bit color + 0xe0, 0x10, 0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xe1, 0x10, 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0x80, 0x0a, // _NORON + 0x29, 0x80, 0x64 // _DISPON }; static bool pmic_init(busio_i2c_obj_t *i2c) { diff --git a/ports/espressif/boards/m5stack_stick_c_plus/board.c b/ports/espressif/boards/m5stack_stick_c_plus/board.c old mode 100755 new mode 100644 index 8188ac9ded0f3..ea43209c2446c --- a/ports/espressif/boards/m5stack_stick_c_plus/board.c +++ b/ports/espressif/boards/m5stack_stick_c_plus/board.c @@ -41,25 +41,25 @@ // display init sequence according to adafruit_st7735r.py library uint8_t display_init_sequence[] = { - 0x01,0x80,0x96, // SWRESET and Delay 150ms - 0x11,0x80,0xff, // SLPOUT and Delay - 0xb1,0x03,0x01,0x2C,0x2D, // _FRMCTR1 - 0xb2,0x03,0x01,0x2C,0x2D, // _FRMCTR2 - 0xb3,0x06,0x01,0x2C,0x2D,0x01,0x2C,0x2D, // _FRMCTR3 - 0xb4,0x01,0x07, // _INVCTR line inversion - 0xc0,0x03,0xa2,0x02,0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA - 0xc1,0x01,0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V - 0xc2,0x02,0x0a,0x00, // _PWCTR3 Opamp current small, Boost frequency - 0xc3,0x02,0x8a,0x2a, - 0xc4,0x02,0x8a,0xee, - 0xc5,0x01,0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V - 0x36,0x01,0xc8, // MADCTL Rotate display - 0x21,0x00, // _INVON - 0x3a,0x01,0x05, // COLMOD - 16bit color - 0xe0,0x10,0x02,0x1c,0x07,0x12,0x37,0x32,0x29,0x2d,0x29,0x25,0x2B,0x39,0x00,0x01,0x03,0x10, // _GMCTRP1 Gamma - 0xe1,0x10,0x03,0x1d,0x07,0x06,0x2E,0x2C,0x29,0x2D,0x2E,0x2E,0x37,0x3F,0x00,0x00,0x02,0x10, // _GMCTRN1 - 0x13,0x80,0x0a, // _NORON - 0x29,0x80,0x64 // _DISPON + 0x01, 0x80, 0x96, // SWRESET and Delay 150ms + 0x11, 0x80, 0xff, // SLPOUT and Delay + 0xb1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR2 + 0xb3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xb4, 0x01, 0x07, // _INVCTR line inversion + 0xc0, 0x03, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 0x01, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 0x02, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 0x02, 0x8a, 0x2a, + 0xc4, 0x02, 0x8a, 0xee, + 0xc5, 0x01, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x36, 0x01, 0xc8, // MADCTL Rotate display + 0x21, 0x00, // _INVON + 0x3a, 0x01, 0x05, // COLMOD - 16bit color + 0xe0, 0x10, 0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xe1, 0x10, 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0x80, 0x0a, // _NORON + 0x29, 0x80, 0x64 // _DISPON }; static bool pmic_init(busio_i2c_obj_t *i2c) { diff --git a/ports/espressif/boards/mixgo_ce_serial/board.c b/ports/espressif/boards/mixgo_ce_serial/board.c index e6ffb553b1ce1..fc592ce4c4a19 100644 --- a/ports/espressif/boards/mixgo_ce_serial/board.c +++ b/ports/espressif/boards/mixgo_ce_serial/board.c @@ -53,7 +53,7 @@ void board_init(void) { // Delete code.Py, use main.py mp_import_stat_t stat_c = mp_import_stat("code.py"); if (stat_c == MP_IMPORT_STAT_FILE) { - f_unlink(fatfs,"/code.py"); + f_unlink(fatfs, "/code.py"); } } diff --git a/ports/espressif/boards/odt_pixelwing_esp32_s2/pins.c b/ports/espressif/boards/odt_pixelwing_esp32_s2/pins.c index 4daec42ae4f42..0fbc5fa26606c 100644 --- a/ports/espressif/boards/odt_pixelwing_esp32_s2/pins.c +++ b/ports/espressif/boards/odt_pixelwing_esp32_s2/pins.c @@ -5,9 +5,9 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_GPIO33) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO33) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_GPIO34) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO34) }, { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO45) }, diff --git a/ports/espressif/common-hal/_bleio/Adapter.c b/ports/espressif/common-hal/_bleio/Adapter.c index 01adae3adb1b2..24452993cb04b 100644 --- a/ports/espressif/common-hal/_bleio/Adapter.c +++ b/ports/espressif/common-hal/_bleio/Adapter.c @@ -142,8 +142,7 @@ bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *s return NULL; } - bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); - address->base.type = &bleio_address_type; + bleio_address_obj_t *address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); common_hal_bleio_address_construct(address, address_bytes, BLEIO_ADDRESS_TYPE_RANDOM_STATIC); return address; } diff --git a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c index cfc6018708ed3..6838f1a8ff581 100644 --- a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c @@ -103,7 +103,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe bleio_characteristic_obj_t *characteristic, mp_float_t timeout, size_t buffer_size) { - uint8_t *buffer = m_malloc(buffer_size, true); + uint8_t *buffer = m_malloc(buffer_size); _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL, false); } diff --git a/ports/espressif/common-hal/_bleio/Connection.c b/ports/espressif/common-hal/_bleio/Connection.c index 5e3e02d8e559e..886113721095c 100644 --- a/ports/espressif/common-hal/_bleio/Connection.c +++ b/ports/espressif/common-hal/_bleio/Connection.c @@ -176,12 +176,7 @@ STATIC int _discovered_service_cb(uint16_t conn_handle, if (_last_discovery_status != BLE_ERR_SUCCESS) { return 0; } - bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); - if (service == NULL) { - _last_discovery_status = BLE_ERR_MEM_CAPACITY; - return 0; - } - service->base.type = &bleio_service_type; + bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); // Initialize several fields at once. bleio_service_from_connection(service, bleio_connection_new_from_internal(self)); @@ -191,12 +186,8 @@ STATIC int _discovered_service_cb(uint16_t conn_handle, service->end_handle = svc->end_handle; service->handle = svc->start_handle; - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - if (uuid == NULL) { - _last_discovery_status = BLE_ERR_MEM_CAPACITY; - return 0; - } - uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); + uuid->nimble_ble_uuid = svc->uuid; service->uuid = uuid; @@ -224,20 +215,12 @@ STATIC int _discovered_characteristic_cb(uint16_t conn_handle, return 0; } - bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); - if (characteristic == NULL) { - _last_discovery_status = BLE_ERR_MEM_CAPACITY; - return 0; - } - characteristic->base.type = &bleio_characteristic_type; + bleio_characteristic_obj_t *characteristic = + mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); // Known characteristic UUID. - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - if (uuid == NULL) { - _last_discovery_status = BLE_ERR_MEM_CAPACITY; - return 0; - } - uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); + uuid->nimble_ble_uuid = chr->uuid; bleio_characteristic_properties_t props = @@ -301,19 +284,9 @@ STATIC int _discovered_descriptor_cb(uint16_t conn_handle, break; } - bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); - if (descriptor == NULL) { - _last_discovery_status = BLE_ERR_MEM_CAPACITY; - return 0; - } - descriptor->base.type = &bleio_descriptor_type; + bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - if (uuid == NULL) { - _last_discovery_status = BLE_ERR_MEM_CAPACITY; - return 0; - } - uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); uuid->nimble_ble_uuid = dsc->uuid; common_hal_bleio_descriptor_construct( @@ -438,8 +411,8 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *interna if (internal->connection_obj != mp_const_none) { return internal->connection_obj; } - bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t); - connection->base.type = &bleio_connection_type; + bleio_connection_obj_t *connection = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type); + connection->connection = internal; internal->connection_obj = connection; diff --git a/ports/espressif/common-hal/_bleio/PacketBuffer.c b/ports/espressif/common-hal/_bleio/PacketBuffer.c index d1d8c24123df3..4e2268f350ac2 100644 --- a/ports/espressif/common-hal/_bleio/PacketBuffer.c +++ b/ports/espressif/common-hal/_bleio/PacketBuffer.c @@ -225,11 +225,11 @@ void common_hal_bleio_packet_buffer_construct( uint32_t *outgoing1 = NULL; uint32_t *outgoing2 = NULL; if (outgoing) { - outgoing1 = m_malloc(max_packet_size, false); + outgoing1 = m_malloc(max_packet_size); // Only allocate the second buffer if we are doing writes with responses. // Without responses, we just write as quickly as we can. if (outgoing == CHAR_PROP_WRITE) { - outgoing2 = m_malloc(max_packet_size, false); + outgoing2 = m_malloc(max_packet_size); } } diff --git a/ports/espressif/common-hal/alarm/__init__.c b/ports/espressif/common-hal/alarm/__init__.c index 0c288d89b45f9..6fa205d01fbe5 100644 --- a/ports/espressif/common-hal/alarm/__init__.c +++ b/ports/espressif/common-hal/alarm/__init__.c @@ -160,20 +160,20 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj esp_sleep_wakeup_cause_t cause = _get_wakeup_cause(false); switch (cause) { case ESP_SLEEP_WAKEUP_TIMER: { - wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms, alarms); break; } case ESP_SLEEP_WAKEUP_GPIO: { - wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms, alarms); break; } case ESP_SLEEP_WAKEUP_TOUCHPAD: { - wake_alarm = alarm_touch_touchalarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_touch_touchalarm_find_triggered_alarm(n_alarms, alarms); break; } #if CIRCUITPY_ESPULP case ESP_SLEEP_WAKEUP_ULP: { - wake_alarm = espulp_ulpalarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = espulp_ulpalarm_find_triggered_alarm(n_alarms, alarms); break; } #endif diff --git a/ports/espressif/common-hal/analogbufio/BufferedIn.c b/ports/espressif/common-hal/analogbufio/BufferedIn.c index 3a8d8d0defbf1..9dd66bc9daa29 100644 --- a/ports/espressif/common-hal/analogbufio/BufferedIn.c +++ b/ports/espressif/common-hal/analogbufio/BufferedIn.c @@ -135,13 +135,13 @@ static void start_dma(analogbufio_bufferedin_obj_t *self, adc_digi_convert_mode_ }; #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"pin:%d, ADC channel:%d, ADC index:%d, adc1_chan_mask:0x%x, adc2_chan_mask:0x%x\n",pin->number,pin->adc_channel,pin->adc_index,adc1_chan_mask,adc2_chan_mask); + mp_printf(&mp_plat_print, "pin:%d, ADC channel:%d, ADC index:%d, adc1_chan_mask:0x%x, adc2_chan_mask:0x%x\n", pin->number, pin->adc_channel, pin->adc_index, adc1_chan_mask, adc2_chan_mask); #endif // DEBUG_ANALOGBUFIO esp_err_t err = adc_digi_initialize(&adc_dma_config); if (ESP_OK != err) { stop_dma(self); common_hal_analogbufio_bufferedin_deinit(self); - mp_raise_ValueError_varg(translate("Unable to initialize ADC DMA controller, ErrorCode:%d"),err); + mp_raise_ValueError_varg(translate("Unable to initialize ADC DMA controller, ErrorCode:%d"), err); } adc_digi_configuration_t dig_cfg = { @@ -154,7 +154,7 @@ static void start_dma(analogbufio_bufferedin_obj_t *self, adc_digi_convert_mode_ }; #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"conversion_mode:%d, format:%d, conv_limit_en:%d, sample_rate:%d\n",*convert_mode,*output_format,ADC_CONV_LIMIT_EN,sample_rate); + mp_printf(&mp_plat_print, "conversion_mode:%d, format:%d, conv_limit_en:%d, sample_rate:%d\n", *convert_mode, *output_format, ADC_CONV_LIMIT_EN, sample_rate); #endif // DEBUG_ANALOGBUFIO adc_digi_pattern_config_t adc_pattern[NUM_ADC_CHANNELS] = {0}; @@ -169,20 +169,20 @@ static void start_dma(analogbufio_bufferedin_obj_t *self, adc_digi_convert_mode_ dig_cfg.adc_pattern = adc_pattern; #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"adc_pattern[0].channel:%d, adc_pattern[0].unit:%d, adc_pattern[0].atten:%d\n",adc_pattern[0].channel,adc_pattern[0].unit,adc_pattern[0].atten); + mp_printf(&mp_plat_print, "adc_pattern[0].channel:%d, adc_pattern[0].unit:%d, adc_pattern[0].atten:%d\n", adc_pattern[0].channel, adc_pattern[0].unit, adc_pattern[0].atten); #endif // DEBUG_ANALOGBUFIO err = adc_digi_controller_configure(&dig_cfg); if (ESP_OK != err) { stop_dma(self); common_hal_analogbufio_bufferedin_deinit(self); - mp_raise_ValueError_varg(translate("Unable to configure ADC DMA controller, ErrorCode:%d"),err); + mp_raise_ValueError_varg(translate("Unable to configure ADC DMA controller, ErrorCode:%d"), err); } err = adc_digi_start(); if (ESP_OK != err) { stop_dma(self); common_hal_analogbufio_bufferedin_deinit(self); - mp_raise_ValueError_varg(translate("Unable to start ADC DMA controller, ErrorCode:%d"),err); + mp_raise_ValueError_varg(translate("Unable to start ADC DMA controller, ErrorCode:%d"), err); } } @@ -251,7 +251,7 @@ uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t start_dma(self, &convert_mode, &output_format); #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"Required bytes: %d\n",len); + mp_printf(&mp_plat_print, "Required bytes: %d\n", len); #endif // DEBUG_ANALOGBUFIO while (captured_bytes < len) { @@ -284,7 +284,7 @@ uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t // For all chips except for ESP32C3 we would receive samples only from one unit // For ESP32C3 we may receive sample from alternating units and need to ignore them #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"Invalid sample received: 0x%x\n",pResult->val); + mp_printf(&mp_plat_print, "Invalid sample received: 0x%x\n", pResult->val); #endif // DEBUG_ANALOGBUFIO stop_dma(self); return captured_samples; @@ -293,13 +293,13 @@ uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t } } else if (ret == ESP_ERR_TIMEOUT) { #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"ADC Timeout\n"); + mp_printf(&mp_plat_print, "ADC Timeout\n"); #endif // DEBUG_ANALOGBUFIO stop_dma(self); return captured_samples; } else { #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"adc_digi_read_bytes failed error code:%d\n",ret); + mp_printf(&mp_plat_print, "adc_digi_read_bytes failed error code:%d\n", ret); #endif // DEBUG_ANALOGBUFIO stop_dma(self); return captured_samples; @@ -308,7 +308,7 @@ uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t stop_dma(self); #if defined(DEBUG_ANALOGBUFIO) - mp_printf(&mp_plat_print,"Captured bytes: %d\n",captured_bytes); + mp_printf(&mp_plat_print, "Captured bytes: %d\n", captured_bytes); #endif // DEBUG_ANALOGBUFIO return captured_samples; } diff --git a/ports/espressif/common-hal/canio/Listener.c b/ports/espressif/common-hal/canio/Listener.c index eccddf6243e4d..66ce09697073e 100644 --- a/ports/espressif/common-hal/canio/Listener.c +++ b/ports/espressif/common-hal/canio/Listener.c @@ -77,7 +77,7 @@ STATIC void install_all_match_filter(canio_listener_obj_t *self) { self->standard = true; } -__attribute__((noinline,optimize("O0"))) +__attribute__((noinline, optimize("O0"))) STATIC void set_filters(canio_listener_obj_t *self, size_t nmatch, canio_match_obj_t **matches) { twai_ll_enter_reset_mode(&TWAI); @@ -162,8 +162,8 @@ mp_obj_t common_hal_canio_listener_receive(canio_listener_obj_t *self) { bool rtr = self->message_in.rtr; int dlc = self->message_in.data_length_code; - canio_message_obj_t *message = m_new_obj(canio_message_obj_t); - message->base.type = rtr ? &canio_remote_transmission_request_type : &canio_message_type; + canio_message_obj_t *message = + mp_obj_malloc(canio_message_obj_t, rtr ? &canio_remote_transmission_request_type : &canio_message_type); message->extended = self->message_in.extd; message->id = self->message_in.identifier; message->size = dlc; diff --git a/ports/espressif/common-hal/espidf/__init__.c b/ports/espressif/common-hal/espidf/__init__.c index d2d00ebc56183..379d7c5ab41a5 100644 --- a/ports/espressif/common-hal/espidf/__init__.c +++ b/ports/espressif/common-hal/espidf/__init__.c @@ -198,4 +198,4 @@ void raise_esp_error(esp_err_t err) { mp_raise_msg_varg(exception_type, translate("%s error 0x%x"), group, err); } -MP_REGISTER_MODULE(MP_QSTR_espidf, espidf_module, CIRCUITPY_ESPIDF); +MP_REGISTER_MODULE(MP_QSTR_espidf, espidf_module); diff --git a/ports/espressif/common-hal/espnow/ESPNow.c b/ports/espressif/common-hal/espnow/ESPNow.c index a048c7f9f1c02..ff07497a304d7 100644 --- a/ports/espressif/common-hal/espnow/ESPNow.c +++ b/ports/espressif/common-hal/espnow/ESPNow.c @@ -143,7 +143,7 @@ void common_hal_espnow_init(espnow_obj_t *self) { } self->recv_buffer = m_new_obj(ringbuf_t); - if (!ringbuf_alloc(self->recv_buffer, self->recv_buffer_size, true)) { + if (!ringbuf_alloc(self->recv_buffer, self->recv_buffer_size /*, true*/)) { m_malloc_fail(self->recv_buffer_size); } diff --git a/ports/espressif/common-hal/mdns/Server.c b/ports/espressif/common-hal/mdns/Server.c index 18c0f0f5e4e03..9205f76087c2c 100644 --- a/ports/espressif/common-hal/mdns/Server.c +++ b/ports/espressif/common-hal/mdns/Server.c @@ -190,7 +190,7 @@ mp_obj_t common_hal_mdns_server_find(mdns_server_obj_t *self, const char *servic // Don't error if we're out of memory. Instead, truncate the tuple. uint8_t added = 0; while (next != NULL) { - mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), GC_ALLOC_FLAG_HAS_FINALISER, false); + mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), GC_ALLOC_FLAG_HAS_FINALISER); if (service == NULL) { if (added == 0) { m_malloc_fail(sizeof(mdns_remoteservice_obj_t)); diff --git a/ports/espressif/common-hal/nvm/ByteArray.c b/ports/espressif/common-hal/nvm/ByteArray.c index a17e368249781..d74de38164ce3 100644 --- a/ports/espressif/common-hal/nvm/ByteArray.c +++ b/ports/espressif/common-hal/nvm/ByteArray.c @@ -66,7 +66,7 @@ static esp_err_t get_bytes(nvs_handle_t handle, uint8_t **buf_out) { *buf_out = NULL; return result; } - buf = gc_alloc(size, 0, false); // this SHOULD be the same as + buf = m_malloc(size); // this SHOULD be the same as if (result == ESP_OK) { result = nvs_get_blob(handle, "data", buf, &size); } else { diff --git a/ports/espressif/common-hal/pulseio/PulseIn.c b/ports/espressif/common-hal/pulseio/PulseIn.c index 42db2f18bd61b..c873f13b4ac23 100644 --- a/ports/espressif/common-hal/pulseio/PulseIn.c +++ b/ports/espressif/common-hal/pulseio/PulseIn.c @@ -95,7 +95,7 @@ void pulsein_reset(void) { void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); + self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index ef564806720c9..9d3c22aca8ed7 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -411,7 +411,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, // Switch to blocking mode for this one call int opts; - opts = lwip_fcntl(self->num,F_GETFL,0); + opts = lwip_fcntl(self->num, F_GETFL, 0); opts = opts & (~O_NONBLOCK); lwip_fcntl(self->num, F_SETFL, opts); diff --git a/ports/espressif/common-hal/wifi/Radio.c b/ports/espressif/common-hal/wifi/Radio.c index 0dcb02a3279f6..e6385ee1e5aaa 100644 --- a/ports/espressif/common-hal/wifi/Radio.c +++ b/ports/espressif/common-hal/wifi/Radio.c @@ -175,8 +175,7 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, u } set_mode_station(self, true); - wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); - scan->base.type = &wifi_scannednetworks_type; + wifi_scannednetworks_obj_t *scan = mp_obj_malloc(wifi_scannednetworks_obj_t, &wifi_scannednetworks_type); self->current_scan = scan; scan->current_channel_index = 0; scan->start_channel = start_channel; @@ -366,8 +365,7 @@ mp_obj_t common_hal_wifi_radio_get_ap_info(wifi_radio_obj_t *self) { return mp_const_none; } - wifi_network_obj_t *ap_info = m_new_obj(wifi_network_obj_t); - ap_info->base.type = &wifi_network_type; + wifi_network_obj_t *ap_info = mp_obj_malloc(wifi_network_obj_t, &wifi_network_type); // From esp_wifi.h, the possible return values (typos theirs): // ESP_OK: succeed // ESP_ERR_WIFI_CONN: The station interface don't initialized diff --git a/ports/espressif/common-hal/wifi/ScannedNetworks.c b/ports/espressif/common-hal/wifi/ScannedNetworks.c index 50df9f8c95adc..e37bdc2f44a86 100644 --- a/ports/espressif/common-hal/wifi/ScannedNetworks.c +++ b/ports/espressif/common-hal/wifi/ScannedNetworks.c @@ -115,8 +115,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) self->channel_scan_in_progress = false; } - wifi_network_obj_t *entry = m_new_obj(wifi_network_obj_t); - entry->base.type = &wifi_network_type; + wifi_network_obj_t *entry = mp_obj_malloc(wifi_network_obj_t, &wifi_network_type); memcpy(&entry->record, &self->results[self->current_result], sizeof(wifi_ap_record_t)); self->current_result++; diff --git a/ports/espressif/i2s_lcd_esp32s2_driver.c b/ports/espressif/i2s_lcd_esp32s2_driver.c index 3b74cc9edaa10..1bf8cd00f3afa 100644 --- a/ports/espressif/i2s_lcd_esp32s2_driver.c +++ b/ports/espressif/i2s_lcd_esp32s2_driver.c @@ -33,7 +33,7 @@ static const char *TAG = "ESP32S2_I2S_LCD"; #define I2S_CHECK(a, str, ret) if (!(a)) { \ - ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ + ESP_LOGE(TAG, "%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ return ret; \ } @@ -401,7 +401,7 @@ i2s_lcd_handle_t i2s_lcd_driver_init(const i2s_lcd_config_t *config) { esp_err_t ret = lcd_cam_init(i2s_lcd_drv, config); if (ESP_OK != ret) { - ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, "i2s lcd driver initialize failed"); + ESP_LOGE(TAG, "%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, "i2s lcd driver initialize failed"); heap_caps_free(i2s_lcd_drv); return NULL; } diff --git a/ports/litex/Makefile b/ports/litex/Makefile index 47a18781f985e..ce7805d067f74 100644 --- a/ports/litex/Makefile +++ b/ports/litex/Makefile @@ -157,8 +157,3 @@ $(BUILD)/firmware.dfu: $(BUILD)/firmware.bin $(PYTHON) $(TOP)/tools/dfu.py -b $^ -D 0x1209:0x5bf0 "$(BUILD)/firmware.dfu" include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/litex/irq.h b/ports/litex/irq.h index 34c8b0a10a0ae..a9814ac7f9c11 100644 --- a/ports/litex/irq.h +++ b/ports/litex/irq.h @@ -41,9 +41,9 @@ static inline unsigned int irq_getie(void) { static inline void irq_setie(unsigned int ie) { if (ie) { - csrs(mstatus,CSR_MSTATUS_MIE); + csrs(mstatus, CSR_MSTATUS_MIE); } else { - csrc(mstatus,CSR_MSTATUS_MIE); + csrc(mstatus, CSR_MSTATUS_MIE); } } diff --git a/ports/litex/supervisor/internal_flash.c b/ports/litex/supervisor/internal_flash.c index 5c58c7bc499cb..3b2b5957dc66f 100644 --- a/ports/litex/supervisor/internal_flash.c +++ b/ports/litex/supervisor/internal_flash.c @@ -92,9 +92,9 @@ static inline void bb_spi_en(unsigned int en) { __attribute__((section(".ramtext"))) static inline void bb_spi_irq_setie(unsigned int ie) { if (ie) { - csrs(mstatus,CSR_MSTATUS_MIE); + csrs(mstatus, CSR_MSTATUS_MIE); } else { - csrc(mstatus,CSR_MSTATUS_MIE); + csrc(mstatus, CSR_MSTATUS_MIE); } } diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile index 24e3c59b13a1a..c02cd79a07662 100644 --- a/ports/mimxrt10xx/Makefile +++ b/ports/mimxrt10xx/Makefile @@ -224,10 +224,6 @@ $(BUILD)/firmware.hex: $(BUILD)/firmware.elf include $(TOP)/py/mkrules.mk -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) # Flash using jlink define jlink_script diff --git a/ports/mimxrt10xx/boards/adafruit_metro_m7_1011_sd/pins.c b/ports/mimxrt10xx/boards/adafruit_metro_m7_1011_sd/pins.c index 8096973aaf9f5..a7256552e5bc8 100644 --- a/ports/mimxrt10xx/boards/adafruit_metro_m7_1011_sd/pins.c +++ b/ports/mimxrt10xx/boards/adafruit_metro_m7_1011_sd/pins.c @@ -30,8 +30,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_05) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_04) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_GPIO_03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_GPIO_03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO_03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_03) }, // SD control { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CD), MP_ROM_PTR(&pin_GPIO_AD_11) }, diff --git a/ports/mimxrt10xx/boards/metro_m7_1011/pins.c b/ports/mimxrt10xx/boards/metro_m7_1011/pins.c index fe03d09764eee..d3b29089cbfc2 100644 --- a/ports/mimxrt10xx/boards/metro_m7_1011/pins.c +++ b/ports/mimxrt10xx/boards/metro_m7_1011/pins.c @@ -30,8 +30,8 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_05) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_04) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_GPIO_03) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_GPIO_03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO_03) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_03) }, // ESP control { MP_OBJ_NEW_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_GPIO_AD_14) }, diff --git a/ports/mimxrt10xx/common-hal/audiobusio/__init__.c b/ports/mimxrt10xx/common-hal/audiobusio/__init__.c index 13ae64d27cb6f..96f9ed813847e 100644 --- a/ports/mimxrt10xx/common-hal/audiobusio/__init__.c +++ b/ports/mimxrt10xx/common-hal/audiobusio/__init__.c @@ -329,7 +329,7 @@ void port_i2s_initialize(i2s_t *self, int instance, sai_transceiver_t *config) { mp_raise_ValueError_varg(translate("Invalid %q"), MP_QSTR_I2SOut); } for (size_t i = 0; i < MP_ARRAY_SIZE(self->buffers); i++) { - self->buffers[i] = m_malloc(AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t), false); + self->buffers[i] = m_malloc(AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t)); } self->peripheral = peripheral; SAI_Init(self->peripheral); diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c index d0698362953a5..c40b2601a03e2 100644 --- a/ports/mimxrt10xx/common-hal/busio/UART.c +++ b/ports/mimxrt10xx/common-hal/busio/UART.c @@ -47,7 +47,7 @@ #if ENABLE_DEBUG_PRINTING #define DBGPrintf mp_printf #else -#define DBGPrintf(p,...) +#define DBGPrintf(p, ...) #endif @@ -348,7 +348,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (self->rx != NULL) { if (receiver_buffer == NULL) { - self->ringbuf = gc_alloc(receiver_buffer_size, false, true /*long-lived*/); + self->ringbuf = gc_alloc(receiver_buffer_size, false); } else { self->ringbuf = receiver_buffer; } diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/clocks.c index bef213a7c7a1b..9906454658384 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/clocks.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/clocks.c @@ -305,7 +305,7 @@ void clocks_init(void) { /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ - IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set GPT1 High frequency reference clock source. */ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK; /* Set GPT2 High frequency reference clock source. */ diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/clocks.c index f62f974bdd25c..95db72df45579 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/clocks.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/clocks.c @@ -370,7 +370,7 @@ void clocks_init(void) { /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ - IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR_MASK; /* Set GPT1 High frequency reference clock source. */ diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/clocks.c index 832ad9afaca33..de12bea6a0dd2 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/clocks.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/clocks.c @@ -383,7 +383,7 @@ void clocks_init(void) { /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ - IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ #if defined(IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK) IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR_MASK; diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c index 0eb879053b90e..2f121240831da 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c @@ -318,7 +318,7 @@ void clocks_init(void) { /* Set SAI3 MCLK3 clock source. */ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ - IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET1 Tx clock source. */ IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false); /* Set ENET2 Tx clock source. */ diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/clocks.c index 1252d481358fb..33ea37c2bdbb0 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/clocks.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/clocks.c @@ -640,7 +640,7 @@ void clocks_init(void) { IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0); /* Set MQS configuration. */ - IOMUXC_MQSConfig(IOMUXC_GPR,kIOMUXC_MqsPwmOverSampleRate32, 0); + IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0); /* Set ENET Ref clock source. */ IOMUXC_GPR->GPR4 &= ~IOMUXC_GPR_GPR4_ENET_REF_CLK_DIR_MASK; /* Set ENET_1G Tx clock source. */ diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c index 997a97ba493c8..6f449286195f5 100644 --- a/ports/mimxrt10xx/supervisor/port.c +++ b/ports/mimxrt10xx/supervisor/port.c @@ -321,7 +321,7 @@ __attribute__((used, naked, no_instrument_function, optimize("no-tree-loop-distr main(); } -void __attribute__((no_instrument_function,section(".itcm.profile_enter"),long_call)) __cyg_profile_func_enter(void *this_fn, +void __attribute__((no_instrument_function, section(".itcm.profile_enter"), long_call)) __cyg_profile_func_enter(void *this_fn, void *call_site) { if ((ITM->TER & (1 << 3)) == 0) { return; @@ -333,7 +333,7 @@ void __attribute__((no_instrument_function,section(".itcm.profile_enter"),long_c ITM->PORT[3].u32 = addr; } -void __attribute__((no_instrument_function,section(".itcm.profile_exit"),long_call)) __cyg_profile_func_exit(void *this_fn, +void __attribute__((no_instrument_function, section(".itcm.profile_exit"), long_call)) __cyg_profile_func_exit(void *this_fn, void *call_site) { if ((ITM->TER & (1 << 4)) == 0) { return; diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index 8a8625bd959f0..5829b465a66ed 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -313,8 +313,3 @@ $(BUILD)/firmware.espruino.zip: $(BUILD)/firmware.hex espruino-dfu-gen: $(BUILD)/firmware.espruino.zip include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c index cf3f9382d7256..e3914e6a18b8a 100644 --- a/ports/nrf/bluetooth/ble_drv.c +++ b/ports/nrf/bluetooth/ble_drv.c @@ -95,7 +95,7 @@ void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { } // Add a new handler to the front of the list - ble_drv_evt_handler_entry_t *handler = m_new_ll(ble_drv_evt_handler_entry_t, 1); + ble_drv_evt_handler_entry_t *handler = m_new(ble_drv_evt_handler_entry_t, 1); ble_drv_add_event_handler_entry(handler, func, param); } diff --git a/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c b/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c index 8714f9bf8ca38..3d41fda40e8fd 100644 --- a/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c +++ b/ports/nrf/boards/Seeed_XIAO_nRF52840_Sense/pins.c @@ -49,10 +49,10 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_PDM_CLK), MP_ROM_PTR(&pin_P1_00) }, { MP_ROM_QSTR(MP_QSTR_PDM_DATA), MP_ROM_PTR(&pin_P0_16) }, - {MP_ROM_QSTR(MP_QSTR_READ_BATT_ENABLE),MP_ROM_PTR(&pin_P0_14)}, - {MP_ROM_QSTR(MP_QSTR_VBATT),MP_ROM_PTR(&pin_P0_31)}, - {MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS),MP_ROM_PTR(&pin_P0_17)}, - {MP_ROM_QSTR(MP_QSTR_CHARGE_RATE),MP_ROM_PTR(&pin_P0_13)}, + {MP_ROM_QSTR(MP_QSTR_READ_BATT_ENABLE), MP_ROM_PTR(&pin_P0_14)}, + {MP_ROM_QSTR(MP_QSTR_VBATT), MP_ROM_PTR(&pin_P0_31)}, + {MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS), MP_ROM_PTR(&pin_P0_17)}, + {MP_ROM_QSTR(MP_QSTR_CHARGE_RATE), MP_ROM_PTR(&pin_P0_13)}, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/nrf/boards/bluemicro833/mpconfigboard.h b/ports/nrf/boards/bluemicro833/mpconfigboard.h index 2340cdc9882c2..8bfeb7cb98ce7 100644 --- a/ports/nrf/boards/bluemicro833/mpconfigboard.h +++ b/ports/nrf/boards/bluemicro833/mpconfigboard.h @@ -42,9 +42,6 @@ #define BOARD_HAS_CRYSTAL 1 -// Take 1k RAM to save 1k flash. -#define CIRCUITPY_PRECOMPUTE_QSTR_ATTR (0) - // Reduce nRF SoftRadio memory usage #define BLEIO_VS_UUID_COUNT 10 #define BLEIO_HVN_TX_QUEUE_SIZE 2 diff --git a/ports/nrf/boards/bluemicro833/mpconfigboard.mk b/ports/nrf/boards/bluemicro833/mpconfigboard.mk index 9b230e9a53cb3..27224e5d1d076 100644 --- a/ports/nrf/boards/bluemicro833/mpconfigboard.mk +++ b/ports/nrf/boards/bluemicro833/mpconfigboard.mk @@ -8,10 +8,11 @@ MCU_CHIP = nrf52833 INTERNAL_FLASH_FILESYSTEM = 1 CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOPWMIO = 0 CIRCUITPY_AUDIOMIXER = 0 CIRCUITPY_KEYPAD = 1 CIRCUITPY_NVM = 0 CIRCUITPY_ONEWIREIO = 0 -CIRCUITPY_PIXELBUF = 1 +CIRCUITPY_PIXELBUF = 1 CIRCUITPY_PIXELMAP = 0 CIRCUITPY_TOUCHIO = 0 diff --git a/ports/nrf/boards/metro_nrf52840_express/pins.c b/ports/nrf/boards/metro_nrf52840_express/pins.c index 44e353ea4af02..3ff4e1756ca0f 100644 --- a/ports/nrf/boards/metro_nrf52840_express/pins.c +++ b/ports/nrf/boards/metro_nrf52840_express/pins.c @@ -39,7 +39,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_15) }, { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_16) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL),MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_13) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_07) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P1_08) }, diff --git a/ports/nrf/boards/pca10100/mpconfigboard.h b/ports/nrf/boards/pca10100/mpconfigboard.h index 8b1ff19a89edd..dca629b422f01 100644 --- a/ports/nrf/boards/pca10100/mpconfigboard.h +++ b/ports/nrf/boards/pca10100/mpconfigboard.h @@ -37,9 +37,6 @@ #define CIRCUITPY_BLE_CONFIG_SIZE (12 * 1024) -// Take 1k RAM to save 1k flash. -#define CIRCUITPY_PRECOMPUTE_QSTR_ATTR (0) - // Reduce nRF SoftRadio memory usage #define BLEIO_VS_UUID_COUNT 10 #define BLEIO_HVN_TX_QUEUE_SIZE 2 diff --git a/ports/nrf/boards/pca10100/mpconfigboard.mk b/ports/nrf/boards/pca10100/mpconfigboard.mk index 356eb16f11537..a081a0db479a8 100644 --- a/ports/nrf/boards/pca10100/mpconfigboard.mk +++ b/ports/nrf/boards/pca10100/mpconfigboard.mk @@ -6,3 +6,6 @@ USB_MANUFACTURER = "Nordic Semiconductor" MCU_CHIP = nrf52833 INTERNAL_FLASH_FILESYSTEM = 1 + +CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_AUDIOMIXER = 0 diff --git a/ports/nrf/boards/ssci_isp1807_dev_board/pins.c b/ports/nrf/boards/ssci_isp1807_dev_board/pins.c index d3188c3644f55..3ae7dad707391 100644 --- a/ports/nrf/boards/ssci_isp1807_dev_board/pins.c +++ b/ports/nrf/boards/ssci_isp1807_dev_board/pins.c @@ -37,11 +37,11 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_P0_06) }, - { MP_ROM_QSTR(MP_QSTR_BUTTON),MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_P1_06) }, - { MP_ROM_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_P0_19) }, - { MP_ROM_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_23) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_12) }, diff --git a/ports/nrf/boards/ssci_isp1807_micro_board/pins.c b/ports/nrf/boards/ssci_isp1807_micro_board/pins.c index 7b7b8833a4af3..9c5358a6a88e9 100644 --- a/ports/nrf/boards/ssci_isp1807_micro_board/pins.c +++ b/ports/nrf/boards/ssci_isp1807_micro_board/pins.c @@ -14,15 +14,15 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_P0_10) }, { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_P0_14) }, { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, - { MP_ROM_QSTR(MP_QSTR_D10),MP_ROM_PTR(&pin_P0_17) }, - { MP_ROM_QSTR(MP_QSTR_D14),MP_ROM_PTR(&pin_P0_08) }, - { MP_ROM_QSTR(MP_QSTR_D15),MP_ROM_PTR(&pin_P0_06) }, - { MP_ROM_QSTR(MP_QSTR_D16),MP_ROM_PTR(&pin_P0_13) }, - { MP_ROM_QSTR(MP_QSTR_D17),MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_D18),MP_ROM_PTR(&pin_P0_02) }, - { MP_ROM_QSTR(MP_QSTR_D19),MP_ROM_PTR(&pin_P0_03) }, - { MP_ROM_QSTR(MP_QSTR_D20),MP_ROM_PTR(&pin_P0_04) }, - { MP_ROM_QSTR(MP_QSTR_D21),MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_P0_05) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_02) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_03) }, @@ -31,10 +31,10 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_29) }, { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_30) }, - { MP_ROM_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P0_31) }, - { MP_ROM_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_P0_29) }, - { MP_ROM_QSTR(MP_QSTR_SCL),MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_23) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_08) }, diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index 828ff8806dadc..e3b8fc22f5a51 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -429,8 +429,7 @@ bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *s ble_gap_addr_t local_address; get_address(self, &local_address); - bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); - address->base.type = &bleio_address_type; + bleio_address_obj_t *address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type); return address; @@ -545,7 +544,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t } self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi); size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX; - uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size, false); + uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size); ble_data_t *sd_data = (ble_data_t *)raw_data; self->scan_results->common_hal_data = sd_data; sd_data->len = max_packet_size; @@ -909,12 +908,11 @@ void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool } // The advertising data buffers must not move, because the SoftDevice depends on them. - // So make them long-lived and reuse them onwards. if (self->advertising_data == NULL) { - self->advertising_data = (uint8_t *)gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false, true); + self->advertising_data = (uint8_t *)gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false); } if (self->scan_response_data == NULL) { - self->scan_response_data = (uint8_t *)gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false, true); + self->scan_response_data = (uint8_t *)gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED * sizeof(uint8_t), false); } memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len); diff --git a/ports/nrf/common-hal/_bleio/Adapter.h b/ports/nrf/common-hal/_bleio/Adapter.h index 4d3fac20c7e7e..8f5b1e892df31 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.h +++ b/ports/nrf/common-hal/_bleio/Adapter.h @@ -45,7 +45,7 @@ extern bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUN typedef struct { mp_obj_base_t base; - // Pointer to buffers we maintain so that the data is long lived. + // We create buffers and copy the advertising data so it will live for as long as we need. uint8_t *advertising_data; uint8_t *scan_response_data; // Pointer to current data. diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c index e911e5a1e30fa..5a70fb9cea252 100644 --- a/ports/nrf/common-hal/_bleio/Characteristic.c +++ b/ports/nrf/common-hal/_bleio/Characteristic.c @@ -102,7 +102,7 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, self->initial_value_len = initial_value_bufinfo->len; if (gc_alloc_possible()) { if (gc_nbytes(initial_value_bufinfo->buf) > 0) { - uint8_t *initial_value = m_malloc(self->initial_value_len, false); + uint8_t *initial_value = m_malloc(self->initial_value_len); memcpy(initial_value, initial_value_bufinfo->buf, self->initial_value_len); self->initial_value = initial_value; } else { diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c index 58dc94fe25db0..0c89a6f2a93e2 100644 --- a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c @@ -116,7 +116,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe bleio_characteristic_obj_t *characteristic, mp_float_t timeout, size_t buffer_size) { - uint8_t *buffer = m_malloc(buffer_size, true); + uint8_t *buffer = m_malloc(buffer_size); _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL, false); } diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c index 69e6945d215b9..5f185de999ad5 100644 --- a/ports/nrf/common-hal/_bleio/Connection.c +++ b/ports/nrf/common-hal/_bleio/Connection.c @@ -466,8 +466,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res for (size_t i = 0; i < response->count; ++i) { ble_gattc_service_t *gattc_service = &response->services[i]; - bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); - service->base.type = &bleio_service_type; + bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); // Initialize several fields at once. bleio_service_from_connection(service, bleio_connection_new_from_internal(connection)); @@ -479,8 +478,7 @@ STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *res if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // Known service UUID. - bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; + bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid); service->uuid = uuid; } else { @@ -504,15 +502,14 @@ STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio for (size_t i = 0; i < response->count; ++i) { ble_gattc_char_t *gattc_char = &response->chars[i]; - bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); - characteristic->base.type = &bleio_characteristic_type; + bleio_characteristic_obj_t *characteristic = + mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); bleio_uuid_obj_t *uuid = NULL; if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // Known characteristic UUID. - uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; + uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid); } else { // The discovery response contained a 128-bit UUID that has not yet been registered with the @@ -571,15 +568,13 @@ STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio break; } - bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); - descriptor->base.type = &bleio_descriptor_type; + bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); bleio_uuid_obj_t *uuid = NULL; if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) { // Known descriptor UUID. - uuid = m_new_obj(bleio_uuid_obj_t); - uuid->base.type = &bleio_uuid_type; + uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid); } else { // The discovery response contained a 128-bit UUID that has not yet been registered with the @@ -763,8 +758,7 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *interna if (internal->connection_obj != mp_const_none) { return internal->connection_obj; } - bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t); - connection->base.type = &bleio_connection_type; + bleio_connection_obj_t *connection = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type); connection->connection = internal; internal->connection_obj = connection; diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.c b/ports/nrf/common-hal/_bleio/PacketBuffer.c index 52402a93f19d8..7a2ccae673ce3 100644 --- a/ports/nrf/common-hal/_bleio/PacketBuffer.c +++ b/ports/nrf/common-hal/_bleio/PacketBuffer.c @@ -298,14 +298,14 @@ void common_hal_bleio_packet_buffer_construct( uint32_t *incoming_buffer = NULL; if (incoming) { incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size); - incoming_buffer = m_malloc(incoming_buffer_size, false); + incoming_buffer = m_malloc(incoming_buffer_size); } uint32_t *outgoing1 = NULL; uint32_t *outgoing2 = NULL; if (outgoing) { - outgoing1 = m_malloc(max_packet_size, false); - outgoing2 = m_malloc(max_packet_size, false); + outgoing1 = m_malloc(max_packet_size); + outgoing2 = m_malloc(max_packet_size); } _common_hal_bleio_packet_buffer_construct(self, characteristic, incoming_buffer, incoming_buffer_size, diff --git a/ports/nrf/common-hal/alarm/__init__.c b/ports/nrf/common-hal/alarm/__init__.c index b3f9979ae0a2f..0835522f4883f 100644 --- a/ports/nrf/common-hal/alarm/__init__.c +++ b/ports/nrf/common-hal/alarm/__init__.c @@ -233,11 +233,11 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj nrf_sleep_source_t cause = _get_wakeup_cause(); switch (cause) { case NRF_SLEEP_WAKEUP_TIMER: { - wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms, alarms); break; } case NRF_SLEEP_WAKEUP_GPIO: { - wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms, alarms); break; } default: diff --git a/ports/nrf/common-hal/audiobusio/I2SOut.c b/ports/nrf/common-hal/audiobusio/I2SOut.c index 6e68583a035d6..35e50162a2838 100644 --- a/ports/nrf/common-hal/audiobusio/I2SOut.c +++ b/ports/nrf/common-hal/audiobusio/I2SOut.c @@ -286,8 +286,8 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, self->buffer_length = sample_rate * buffer_length_ms * self->bytes_per_sample * self->channel_count / 1000; self->buffer_length = (self->buffer_length + 3) & ~3; - self->buffers[0] = m_malloc(self->buffer_length, false); - self->buffers[1] = m_malloc(self->buffer_length, false); + self->buffers[0] = m_malloc(self->buffer_length); + self->buffers[1] = m_malloc(self->buffer_length); audiosample_reset_buffer(self->sample, false, 0); diff --git a/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c index bc6302cb427fa..2334db851a4da 100644 --- a/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/nrf/common-hal/audiopwmio/PWMAudioOut.c @@ -266,9 +266,9 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, mp_arg_validate_length_max(max_buffer_length, UINT16_MAX, MP_QSTR_buffer); uint16_t buffer_length = (uint16_t)max_buffer_length; - self->buffers[0] = m_malloc(buffer_length * 2 * sizeof(uint16_t), false); + self->buffers[0] = m_malloc(buffer_length * 2 * sizeof(uint16_t)); if (!self->single_buffer) { - self->buffers[1] = m_malloc(buffer_length * 2 * sizeof(uint16_t), false); + self->buffers[1] = m_malloc(buffer_length * 2 * sizeof(uint16_t)); } diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 1c63e730921b2..5c44ab16d548f 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -215,13 +215,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (receiver_buffer != NULL) { ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { - // Initially allocate the UART's buffer in the long-lived part of the - // heap. UARTs are generally long-lived objects, but the "make long- - // lived" machinery is incapable of moving internal pointers like - // self->buffer, so do it manually. (However, as long as internal - // pointers like this are NOT moved, allocating the buffer - // in the long-lived pool is not strictly necessary) - if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size)) { nrfx_uarte_uninit(self->uarte); m_malloc_fail(receiver_buffer_size); } @@ -359,7 +353,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, if (!nrfx_is_in_ram(data)) { // Allocate long strings on the heap. if (len > 128 && gc_alloc_possible()) { - tx_buf = (uint8_t *)gc_alloc(len, false, false); + tx_buf = (uint8_t *)m_malloc(len); } else { tx_buf = alloca(len); } diff --git a/ports/nrf/common-hal/microcontroller/__init__.c b/ports/nrf/common-hal/microcontroller/__init__.c index 7824175605ac1..40f60f90def45 100644 --- a/ports/nrf/common-hal/microcontroller/__init__.c +++ b/ports/nrf/common-hal/microcontroller/__init__.c @@ -82,9 +82,9 @@ void common_hal_mcu_enable_interrupts() { void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { enum { DFU_MAGIC_UF2_RESET = 0x57 }; if (runmode == RUNMODE_BOOTLOADER || runmode == RUNMODE_UF2) { - sd_power_gpregret_set(0,DFU_MAGIC_UF2_RESET); + sd_power_gpregret_set(0, DFU_MAGIC_UF2_RESET); } else { - sd_power_gpregret_set(0,0); + sd_power_gpregret_set(0, 0); } if (runmode == RUNMODE_SAFE_MODE) { safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); diff --git a/ports/nrf/common-hal/pulseio/PulseIn.c b/ports/nrf/common-hal/pulseio/PulseIn.c index 757c56a4ac289..0c1452f5a023a 100644 --- a/ports/nrf/common-hal/pulseio/PulseIn.c +++ b/ports/nrf/common-hal/pulseio/PulseIn.c @@ -127,7 +127,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu } _objs[idx] = self; - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); + self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile index f63575041530a..4ae03bff52622 100644 --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -39,7 +39,7 @@ INC_CYW43 := \ -isystem sdk/src/rp2_common/pico_lwip/include/ \ -isystem sdk/src/rp2_common/pico_rand/include/ \ -CFLAGS_CYW43 := -DCYW43_LWIP=1 -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_USE_SPI -DIGNORE_GPIO25 -DIGNORE_GPIO23 -DIGNORE_GPIO24 -DCYW43_LOGIC_DEBUG=0 -DCYW43_NETUTILS=1 +CFLAGS_CYW43 := -DCYW43_LWIP=1 -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_USE_SPI -DIGNORE_GPIO25 -DIGNORE_GPIO23 -DIGNORE_GPIO24 -DCYW43_LOGIC_DEBUG=0 -DCYW43_NETUTILS=1 -DPICO_BUILD SRC_SDK_CYW43 := \ src/common/pico_sync/sem.c \ src/rp2_common/pico_async_context/async_context_base.c \ @@ -465,8 +465,3 @@ $(BUILD)/firmware.uf2: $(BUILD)/firmware.bin $(Q)$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xe48bff56 -b 0x10000000 -c -o $@ $^ include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/raspberrypi/bindings/cyw43/__init__.c b/ports/raspberrypi/bindings/cyw43/__init__.c index 520d10263c3ab..d00612518e686 100644 --- a/ports/raspberrypi/bindings/cyw43/__init__.c +++ b/ports/raspberrypi/bindings/cyw43/__init__.c @@ -155,4 +155,4 @@ const mp_obj_module_t cyw43_module = { .globals = (mp_obj_dict_t *)&cyw43_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_cyw43, cyw43_module, CIRCUITPY_CYW43); +MP_REGISTER_MODULE(MP_QSTR_cyw43, cyw43_module); diff --git a/ports/raspberrypi/bindings/picodvi/__init__.c b/ports/raspberrypi/bindings/picodvi/__init__.c index edfe7759c86c4..878da11d0c0f3 100644 --- a/ports/raspberrypi/bindings/picodvi/__init__.c +++ b/ports/raspberrypi/bindings/picodvi/__init__.c @@ -45,4 +45,4 @@ const mp_obj_module_t picodvi_module = { .globals = (mp_obj_dict_t *)&picodvi_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_picodvi, picodvi_module, CIRCUITPY_PICODVI); +MP_REGISTER_MODULE(MP_QSTR_picodvi, picodvi_module); diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c index cce64ac8c368d..d5924277c8fc4 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.c +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c @@ -159,8 +159,7 @@ //| ... STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - rp2pio_statemachine_obj_t *self = m_new_obj(rp2pio_statemachine_obj_t); - self->base.type = &rp2pio_statemachine_type; + rp2pio_statemachine_obj_t *self = mp_obj_malloc(rp2pio_statemachine_obj_t, &rp2pio_statemachine_type); enum { ARG_program, ARG_frequency, ARG_init, ARG_may_exec, ARG_first_out_pin, ARG_out_pin_count, ARG_initial_out_pin_state, ARG_initial_out_pin_direction, ARG_first_in_pin, ARG_in_pin_count, @@ -176,7 +175,7 @@ STATIC mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n ARG_user_interruptible, ARG_wrap_target, ARG_wrap, - ARG_offset,}; + ARG_offset, }; static const mp_arg_t allowed_args[] = { { MP_QSTR_program, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_frequency, MP_ARG_REQUIRED | MP_ARG_INT }, diff --git a/ports/raspberrypi/bindings/rp2pio/__init__.c b/ports/raspberrypi/bindings/rp2pio/__init__.c index 193a3a2025223..ed2eced8ea968 100644 --- a/ports/raspberrypi/bindings/rp2pio/__init__.c +++ b/ports/raspberrypi/bindings/rp2pio/__init__.c @@ -72,4 +72,4 @@ const mp_obj_module_t rp2pio_module = { .globals = (mp_obj_dict_t *)&rp2pio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_rp2pio, rp2pio_module, CIRCUITPY_RP2PIO); +MP_REGISTER_MODULE(MP_QSTR_rp2pio, rp2pio_module); diff --git a/ports/raspberrypi/common-hal/alarm/__init__.c b/ports/raspberrypi/common-hal/alarm/__init__.c index f6d36f702e067..da081351dc389 100644 --- a/ports/raspberrypi/common-hal/alarm/__init__.c +++ b/ports/raspberrypi/common-hal/alarm/__init__.c @@ -168,11 +168,11 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj uint8_t cause = _get_wakeup_cause(); switch (cause) { case RP_SLEEP_WAKEUP_RTC: { - wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms, alarms); break; } case RP_SLEEP_WAKEUP_GPIO: { - wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms, alarms); break; } default: diff --git a/ports/raspberrypi/common-hal/busio/UART.c b/ports/raspberrypi/common-hal/busio/UART.c index 28cfc8b0525c7..2e200a5abfefc 100644 --- a/ports/raspberrypi/common-hal/busio/UART.c +++ b/ports/raspberrypi/common-hal/busio/UART.c @@ -159,13 +159,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (receiver_buffer != NULL) { ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { - // Initially allocate the UART's buffer in the long-lived part of the - // heap. UARTs are generally long-lived objects, but the "make long- - // lived" machinery is incapable of moving internal pointers like - // self->buffer, so do it manually. (However, as long as internal - // pointers like this are NOT moved, allocating the buffer - // in the long-lived pool is not strictly necessary) - if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size)) { uart_deinit(self->uart); m_malloc_fail(receiver_buffer_size); } diff --git a/ports/raspberrypi/common-hal/mdns/Server.c b/ports/raspberrypi/common-hal/mdns/Server.c index ab0a7079af200..c21d8130408d8 100644 --- a/ports/raspberrypi/common-hal/mdns/Server.c +++ b/ports/raspberrypi/common-hal/mdns/Server.c @@ -230,7 +230,7 @@ STATIC void alloc_search_result_cb(struct mdns_answer *answer, const char *varpa if ((flags & MDNS_SEARCH_RESULT_FIRST) != 0) { // first - mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), 0, false); + mdns_remoteservice_obj_t *service = m_malloc(sizeof(mdns_remoteservice_obj_t)); if (service == NULL) { // alloc fails mdns_search_stop(state->request_id); diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index 2d21713e60698..a074ee3604db1 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -47,7 +47,7 @@ static const uint16_t pulsein_program[] = { void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); + self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } @@ -79,7 +79,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, common_hal_pulseio_pulsein_pause(self); - common_hal_rp2pio_statemachine_set_interrupt_handler(&(self->state_machine),&common_hal_pulseio_pulsein_interrupt,self,PIO_IRQ0_INTE_SM0_RXNEMPTY_BITS); + common_hal_rp2pio_statemachine_set_interrupt_handler(&(self->state_machine), &common_hal_pulseio_pulsein_interrupt, self, PIO_IRQ0_INTE_SM0_RXNEMPTY_BITS); common_hal_pulseio_pulsein_resume(self, 0); } @@ -102,7 +102,7 @@ void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self) { void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t *self) { pio_sm_restart(self->state_machine.pio, self->state_machine.state_machine); pio_sm_set_enabled(self->state_machine.pio, self->state_machine.state_machine, false); - pio_sm_clear_fifos(self->state_machine.pio,self->state_machine.state_machine); + pio_sm_clear_fifos(self->state_machine.pio, self->state_machine.state_machine); self->last_level = self->idle_state; self->level_count = 0; self->paused = true; @@ -149,18 +149,18 @@ void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t *self, common_hal_pulseio_pulsein_pause(self); // Send the trigger pulse. if (trigger_duration > 0) { - gpio_set_function(self->pin,GPIO_FUNC_SIO); - gpio_set_dir(self->pin,true); + gpio_set_function(self->pin, GPIO_FUNC_SIO); + gpio_set_dir(self->pin, true); gpio_put(self->pin, !self->idle_state); common_hal_mcu_delay_us((uint32_t)trigger_duration); - gpio_set_function(self->pin,GPIO_FUNC_PIO0); + gpio_set_function(self->pin, GPIO_FUNC_PIO0); } // exec a wait for the selected pin to change state if (self->idle_state == true) { - pio_sm_exec(self->state_machine.pio,self->state_machine.state_machine,0x2020); + pio_sm_exec(self->state_machine.pio, self->state_machine.state_machine, 0x2020); } else { - pio_sm_exec(self->state_machine.pio,self->state_machine.state_machine,0x20a0); + pio_sm_exec(self->state_machine.pio, self->state_machine.state_machine, 0x20a0); } pio_sm_set_enabled(self->state_machine.pio, self->state_machine.state_machine, true); self->paused = false; diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index 0583e4f803390..629811ab9f481 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -151,7 +151,7 @@ void reset_rp2pio_statemachine(void) { irq_handler_t int_handler = irq_get_exclusive_handler(irq); if (int_handler > 0) { irq_set_enabled(irq, false); - irq_remove_handler(irq,int_handler); + irq_remove_handler(irq, int_handler); } } } diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index 0696cc7ae9afe..f2b84f9ccb85b 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -733,8 +733,7 @@ socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_ mp_raise_NotImplementedError(translate("Only IPv4 sockets supported")); } - // we must allocate sockets long-lived because we depend on their object-identity - socketpool_socket_obj_t *socket = m_new_ll_obj_with_finaliser(socketpool_socket_obj_t); + socketpool_socket_obj_t *socket = m_new_obj_with_finaliser(socketpool_socket_obj_t); socket->base.type = &socketpool_socket_type; if (!socketpool_socket(self, family, type, socket)) { diff --git a/ports/raspberrypi/common-hal/wifi/Radio.c b/ports/raspberrypi/common-hal/wifi/Radio.c index 8571d490c4813..7ccb41c0d63ca 100644 --- a/ports/raspberrypi/common-hal/wifi/Radio.c +++ b/ports/raspberrypi/common-hal/wifi/Radio.c @@ -137,8 +137,7 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, u if (!common_hal_wifi_radio_get_enabled(self)) { mp_raise_RuntimeError(translate("Wifi is not enabled")); } - wifi_scannednetworks_obj_t *scan = m_new_obj(wifi_scannednetworks_obj_t); - scan->base.type = &wifi_scannednetworks_type; + wifi_scannednetworks_obj_t *scan = mp_obj_malloc(wifi_scannednetworks_obj_t, &wifi_scannednetworks_type); mp_obj_t args[] = { mp_const_empty_tuple, MP_OBJ_NEW_SMALL_INT(16) }; scan->results = mp_type_deque.make_new(&mp_type_deque, 2, 0, args); self->current_scan = scan; diff --git a/ports/raspberrypi/common-hal/wifi/ScannedNetworks.c b/ports/raspberrypi/common-hal/wifi/ScannedNetworks.c index 97299e2f742b1..e2de56a6d62ef 100644 --- a/ports/raspberrypi/common-hal/wifi/ScannedNetworks.c +++ b/ports/raspberrypi/common-hal/wifi/ScannedNetworks.c @@ -97,8 +97,7 @@ mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) } - wifi_network_obj_t *entry = m_new_obj(wifi_network_obj_t); - entry->base.type = &wifi_network_type; + wifi_network_obj_t *entry = mp_obj_malloc(wifi_network_obj_t, &wifi_network_type); scan_result_get(&entry->record); return MP_OBJ_FROM_PTR(entry); diff --git a/ports/silabs/Makefile b/ports/silabs/Makefile index 66749b4320c0b..71092afcbf1ad 100644 --- a/ports/silabs/Makefile +++ b/ports/silabs/Makefile @@ -38,8 +38,6 @@ PY_GEN_PINS_SRC ?= tools/make_pins.py # SLC tool path SLC_PATH = $(realpath $(CURDIR))/tools/slc_cli_linux -BUILD_VERBOSE ?= 1 - CFLAGS = $(INCLUDES) $(C_DEFS) $(C_FLAGS) \ -Wno-expansion-to-defined \ -Wno-unused-parameter \ @@ -95,23 +93,18 @@ endif SRC_S = boards/mp_efr32xg24_gchelper.s SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) # There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, # because a few modules have files both in common-hal/ and shared-module/. # Doing a $(sort ...) removes duplicates as part of sorting. SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) -ifneq ($(FROZEN_MPY_DIR),) -FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') -FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) -endif - OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) @@ -145,7 +138,7 @@ $(OUTPUT_DIR)/firmware.bin: $(SILABS_BUILD)/$(PROJECTNAME).Makefile $(OUTPUT_DIR @echo 'Done.' endif -$(SILABS_BUILD)/$(PROJECTNAME).Makefile: +$(SILABS_BUILD)/$(PROJECTNAME).Makefile: | $(HEADER_BUILD)/mpversion.h +@$(MAKE) --no-print-directory slc-generate $(OUTPUT_DIR)/firmware.out: $(SILABS_BUILD)/pin_functions.h $(SILABS_BUILD)/pins.c $(OBJ) $(OBJS) $(LIB_FILES) @@ -181,38 +174,37 @@ endif @sed -i 's/ autogen\// $(SILABS_BUILD)\/autogen\//g' $(SILABS_BUILD)/circuitpython_efr32.project.mak @sed -i 's/-T"autogen\//-T"$(SILABS_BUILD)\/autogen\//g' $(SILABS_BUILD)/circuitpython_efr32.project.mak -#Override ECHO +# tools/slc_cli_linux/bin/slc-cli/developer/exporter_templates/arm_gcc/arm_gcc.Makefile defines +# ECHO = @ +# which is not compatible with py/mkenv.mk: +# ECHO = @echo +# so override ECHO $(OBJS): ECHO = -$(OBJS): +#$(OBJS): $(OUTPUT_DIR)/%.o: %.c - @echo 'Building $<' + #@echo 'Building $<' @$(MKDIR_P) $(@D) - $(ECHO)$(CC) $(CFLAGS) -c -o $@ $< + @$(CC) $(CFLAGS) -c -o $@ $< $(OUTPUT_DIR)/%.o: %.cpp - @echo 'Building $<' + #@echo 'Building $<' @$(MKDIR_P) $(@D) - $(ECHO)$(CXX) $(CXXFLAGS) -c -o $@ $< + @$(CXX) $(CXXFLAGS) -c -o $@ $< $(OUTPUT_DIR)/%.o: %.cc - @echo 'Building $<' + #@echo 'Building $<' @$(MKDIR_P) $(@D) - $(ECHO)$(CXX) $(CXXFLAGS) -c -o $@ $< + @$(CXX) $(CXXFLAGS) -c -o $@ $< $(OUTPUT_DIR)/%.o: %.s - @echo 'Building $<' + #@echo 'Building $<' @$(MKDIR_P) $(@D) - $(ECHO)$(CC) $(ASMFLAGS) -c -o $@ $< + @$(CC) $(ASMFLAGS) -c -o $@ $< $(OUTPUT_DIR)/%.o: %.S - @echo 'Building $<' + #@echo 'Building $<' @$(MKDIR_P) $(@D) - $(ECHO)$(CC) $(ASMFLAGS) -c -o $@ $< + @$(CC) $(ASMFLAGS) -c -o $@ $< include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c b/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c index cdffa9f1e5204..d981f416ab79b 100644 --- a/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c +++ b/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c @@ -37,7 +37,8 @@ #include "sl_sensor_hall.h" #include "sl_sensor_pressure.h" -STATIC mp_obj_t sensor_init(busio_i2c_obj_t *i2c) { +STATIC mp_obj_t sensor_init(mp_obj_t i2c_in) { + // busio_i2c_obj_t *i2c = MP_OBJ_TO_PTR(i2c_in); sl_status_t sc; if (!common_hal_mcu_pin_is_free(&pin_PC9)) { @@ -167,9 +168,9 @@ STATIC mp_obj_t sensor_imu_get(void) { avec_obj[0] = mp_obj_new_int(avec[0]); avec_obj[1] = mp_obj_new_int(avec[1]); avec_obj[2] = mp_obj_new_int(avec[2]); - ret[0] = mp_obj_new_list(3,ovec_obj); - ret[1] = mp_obj_new_list(3,avec_obj); - return mp_obj_new_tuple(2,ret); + ret[0] = mp_obj_new_list(3, ovec_obj); + ret[1] = mp_obj_new_list(3, avec_obj); + return mp_obj_new_tuple(2, ret); } STATIC mp_obj_t sensor_imu_calibrate(void) { @@ -181,15 +182,15 @@ STATIC mp_obj_t sensor_imu_calibrate(void) { return mp_const_true; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(sensor_init_obj,sensor_init); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_deinit_obj,sensor_deinit); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_temperature_obj,sensor_get_temperature); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_humidity_obj,sensor_get_humidity); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_lux_obj,sensor_get_lux); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_hall_obj,sensor_get_hall); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_pressure_obj,sensor_get_pressure); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_imu_get_obj,sensor_imu_get); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_imu_calibrate_obj,sensor_imu_calibrate); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(sensor_init_obj, sensor_init); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_deinit_obj, sensor_deinit); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_temperature_obj, sensor_get_temperature); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_humidity_obj, sensor_get_humidity); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_lux_obj, sensor_get_lux); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_hall_obj, sensor_get_hall); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_get_pressure_obj, sensor_get_pressure); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_imu_get_obj, sensor_imu_get); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(sensor_imu_calibrate_obj, sensor_imu_calibrate); STATIC const mp_rom_map_elem_t sensor_globals_table[] = { @@ -211,4 +212,4 @@ const mp_obj_module_t sensor_module = { .globals = (mp_obj_dict_t *)&sensor_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_sensor, sensor_module,1); +MP_REGISTER_MODULE(MP_QSTR_sensor, sensor_module); diff --git a/ports/silabs/common-hal/_bleio/Adapter.c b/ports/silabs/common-hal/_bleio/Adapter.c index ec2e6632ecd3f..4d592f4422184 100644 --- a/ports/silabs/common-hal/_bleio/Adapter.c +++ b/ports/silabs/common-hal/_bleio/Adapter.c @@ -127,8 +127,7 @@ bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *s return NULL; } - address = m_new_obj(bleio_address_obj_t); - address->base.type = &bleio_address_type; + address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); common_hal_bleio_address_construct(address, get_address.addr, BLEIO_ADDRESS_TYPE_RANDOM_STATIC); return address; diff --git a/ports/silabs/common-hal/_bleio/Characteristic.c b/ports/silabs/common-hal/_bleio/Characteristic.c index a39180b19b77c..d713e04d00852 100644 --- a/ports/silabs/common-hal/_bleio/Characteristic.c +++ b/ports/silabs/common-hal/_bleio/Characteristic.c @@ -193,9 +193,9 @@ size_t common_hal_bleio_characteristic_get_value( if (common_hal_bleio_service_get_is_remote(self->service)) { // ble client gets characteristic value if (BT_GATT_CHRC_READ & self->props) { - sc = sl_bt_gatt_read_characteristic_value(conn_handle,self->handle); + sc = sl_bt_gatt_read_characteristic_value(conn_handle, self->handle); while (SL_STATUS_OK != sc && retry > 0) { - sc = sl_bt_gatt_read_characteristic_value(conn_handle,self->handle); + sc = sl_bt_gatt_read_characteristic_value(conn_handle, self->handle); vTaskDelay(100 / portTICK_PERIOD_MS); retry--; } @@ -372,7 +372,7 @@ void common_hal_bleio_characteristic_add_descriptor( // Set the remote characteristic’s CCCD to enable or disable notification and indication. void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, - bool notify,bool indicate) { + bool notify, bool indicate) { sl_status_t sc = SL_STATUS_FAIL; @@ -383,7 +383,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, indicate = 0; if (notify) { sc = sl_bt_gatt_set_characteristic_notification(conn_handle, - self->handle,sl_bt_gatt_notification); + self->handle, sl_bt_gatt_notification); if (SL_STATUS_OK != sc) { mp_raise_bleio_BluetoothError(translate("Notify fail")); } @@ -391,7 +391,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, if (indicate) { sc = sl_bt_gatt_set_characteristic_notification(conn_handle, - self->handle,sl_bt_gatt_indication); + self->handle, sl_bt_gatt_indication); if (SL_STATUS_OK != sc) { mp_raise_bleio_BluetoothError(translate("Indicate fail")); } @@ -399,7 +399,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, if (0 == notify && 0 == indicate) { sc = sl_bt_gatt_set_characteristic_notification(conn_handle, - self->handle,sl_bt_gatt_disable); + self->handle, sl_bt_gatt_disable); if (SL_STATUS_OK != sc) { mp_raise_bleio_BluetoothError(translate("Indicate fail")); } diff --git a/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c index 653de697cda39..2acb6b00fcab9 100644 --- a/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c @@ -57,7 +57,7 @@ bool characteristic_buffer_on_ble_evt(uint16_t attribute, } } } else { - ringbuf_put_n(&bleio_characteristic_buffer_list.data[cindex]->ringbuf,data, len); + ringbuf_put_n(&bleio_characteristic_buffer_list.data[cindex]->ringbuf, data, len); } taskEXIT_CRITICAL(); @@ -87,7 +87,7 @@ void common_hal_bleio_characteristic_buffer_construct( mp_float_t timeout, size_t buffer_size) { - uint8_t *buffer = m_malloc(buffer_size, true); + uint8_t *buffer = m_malloc(buffer_size); _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, diff --git a/ports/silabs/common-hal/_bleio/Connection.c b/ports/silabs/common-hal/_bleio/Connection.c index ad3f6db198378..27adc49e91f8d 100644 --- a/ports/silabs/common-hal/_bleio/Connection.c +++ b/ports/silabs/common-hal/_bleio/Connection.c @@ -101,7 +101,7 @@ mp_float_t common_hal_bleio_connection_get_connection_interval( mp_int_t common_hal_bleio_connection_get_max_packet_length( bleio_connection_internal_t *self) { - sl_status_t sc = sl_bt_gatt_server_get_mtu(self->conn_handle,&self->mtu); + sl_status_t sc = sl_bt_gatt_server_get_mtu(self->conn_handle, &self->mtu); if (sc != SL_STATUS_OK) { mp_raise_bleio_BluetoothError(translate("gatt_server_get_mtu fail.")); } @@ -136,7 +136,7 @@ mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services( xdiscovery_event = xEventGroupCreate(); if (xdiscovery_event != NULL) { - xEventGroupClearBits(xdiscovery_event,1 << 0); + xEventGroupClearBits(xdiscovery_event, 1 << 0); } self->connection->remote_service_list = mp_obj_new_list(0, NULL); bleio_connection_ensure_connected(self); @@ -161,7 +161,7 @@ mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services( ux_bits = xEventGroupWaitBits( xdiscovery_event, 1 << 0, - pdTRUE,pdFALSE, + pdTRUE, pdFALSE, DISCOVERY_TIMEOUT_MS / portTICK_PERIOD_MS); if ((ux_bits & (1 << 0)) == (1 << 0)) { @@ -189,7 +189,7 @@ mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services( uuid16_value[0] = uuid->efr_ble_uuid.uuid16.value & 0xff; uuid16_value[1] = uuid->efr_ble_uuid.uuid16.value >> 8; sc = sl_bt_gatt_discover_primary_services_by_uuid( - self->connection->conn_handle,2,uuid16_value); + self->connection->conn_handle, 2, uuid16_value); } else if (BLE_UUID_TYPE_128 == uuid->efr_ble_uuid.uuid.type) { sc = sl_bt_gatt_discover_primary_services_by_uuid( @@ -251,8 +251,7 @@ mp_obj_t bleio_connection_new_from_internal( if (internal->connection_obj != mp_const_none) { return internal->connection_obj; } - connection = m_new_obj(bleio_connection_obj_t); - connection->base.type = &bleio_connection_type; + connection = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type); connection->connection = internal; internal->connection_obj = connection; diff --git a/ports/silabs/common-hal/_bleio/PacketBuffer.c b/ports/silabs/common-hal/_bleio/PacketBuffer.c index dd74e1709925c..f771983a61aa6 100644 --- a/ports/silabs/common-hal/_bleio/PacketBuffer.c +++ b/ports/silabs/common-hal/_bleio/PacketBuffer.c @@ -223,12 +223,12 @@ void common_hal_bleio_packet_buffer_construct( if (incoming) { incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size); - incoming_buffer = m_malloc(incoming_buffer_size, false); + incoming_buffer = m_malloc(incoming_buffer_size); } if (outgoing) { - outgoing1 = m_malloc(max_packet_size, false); - outgoing2 = m_malloc(max_packet_size, false); + outgoing1 = m_malloc(max_packet_size); + outgoing2 = m_malloc(max_packet_size); } _common_hal_bleio_packet_buffer_construct(self, characteristic, incoming_buffer, incoming_buffer_size, diff --git a/ports/silabs/common-hal/_bleio/__init__.c b/ports/silabs/common-hal/_bleio/__init__.c index 79a0b764e9c72..041fdc38b7cdf 100644 --- a/ports/silabs/common-hal/_bleio/__init__.c +++ b/ports/silabs/common-hal/_bleio/__init__.c @@ -125,13 +125,13 @@ void sl_bt_on_event(sl_bt_msg_t *evt) { sl_bt_system_get_identity_address(&address, &address_type); snprintf((char *)device_name, 14 + 1, - "CIRCUITPY-%X%X",address.addr[1], address.addr[0]); + "CIRCUITPY-%X%X", address.addr[1], address.addr[0]); sl_bt_gatt_server_write_attribute_value(gattdb_device_name, - 0,14,device_name); + 0, 14, device_name); - sl_bt_sm_store_bonding_configuration(5,2); + sl_bt_sm_store_bonding_configuration(5, 2); - sl_bt_sm_configure(0x00,sl_bt_sm_io_capability_noinputnooutput); + sl_bt_sm_configure(0x00, sl_bt_sm_io_capability_noinputnooutput); sl_bt_sm_set_bondable_mode(1); break; @@ -162,7 +162,7 @@ void sl_bt_on_event(sl_bt_msg_t *evt) { &evt->data.evt_scanner_legacy_advertisement_report.data); if (xscan_event != NULL) { - xEventGroupSetBits(xscan_event,1 << 0); + xEventGroupSetBits(xscan_event, 1 << 0); } break; @@ -183,17 +183,12 @@ void sl_bt_on_event(sl_bt_msg_t *evt) { osMutexAcquire(bluetooth_connection_mutex_id, osWaitForever); connection = bleio_conn_handle_to_connection( evt->data.evt_gatt_service.connection); - service = m_new_obj(bleio_service_obj_t); - if (NULL == service) { - mp_raise_bleio_BluetoothError( - translate("Create new service obj fail")); - } - service->base.type = &bleio_service_type; + service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); bleio_service_from_connection(service, bleio_connection_new_from_internal(connection)); service->is_remote = true; service->handle = evt->data.evt_gatt_service.service; - uuid = m_new_obj(bleio_uuid_obj_t); + uuid = m_new_obj_maybe(bleio_uuid_obj_t); if (NULL == uuid) { osMutexRelease(bluetooth_connection_mutex_id); mp_raise_bleio_BluetoothError( @@ -231,21 +226,8 @@ void sl_bt_on_event(sl_bt_msg_t *evt) { service = MP_OBJ_TO_PTR(connection->remote_service_list->items[serv_idx - 1]); - characteristic = m_new_obj(bleio_characteristic_obj_t); - if (characteristic == NULL) { - mp_raise_bleio_BluetoothError( - translate("Create new characteristic obj fail.")); - } - - characteristic->base.type = &bleio_characteristic_type; - uuid = m_new_obj(bleio_uuid_obj_t); - if (uuid == NULL) { - mp_raise_bleio_BluetoothError( - translate("Create new characteristic uuid obj fail.")); - break; - } - - uuid->base.type = &bleio_uuid_type; + characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); + uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); if (UUID16_LEN == evt->data.evt_gatt_characteristic.uuid.len) { uuid->efr_ble_uuid.uuid16.value &= 0x0000; uuid->efr_ble_uuid.uuid16.value @@ -307,7 +289,7 @@ void sl_bt_on_event(sl_bt_msg_t *evt) { conn_state = RUNNING; serv_idx = 0; if (xdiscovery_event != NULL) { - xEventGroupSetBits(xdiscovery_event,1 << 0); + xEventGroupSetBits(xdiscovery_event, 1 << 0); } } } @@ -356,7 +338,7 @@ void sl_bt_on_event(sl_bt_msg_t *evt) { break; case sl_bt_evt_sm_confirm_bonding_id: - sl_bt_sm_bonding_confirm(evt->data.evt_sm_confirm_bonding.connection,1); + sl_bt_sm_bonding_confirm(evt->data.evt_sm_confirm_bonding.connection, 1); break; case sl_bt_evt_sm_bonded_id: diff --git a/ports/silabs/common-hal/busio/UART.c b/ports/silabs/common-hal/busio/UART.c index 75c46f4725039..813432e9aaa8f 100644 --- a/ports/silabs/common-hal/busio/UART.c +++ b/ports/silabs/common-hal/busio/UART.c @@ -111,7 +111,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uartdrv_usart_init.txQueue = (UARTDRV_Buffer_FifoQueue_t *) &uartdrv_usart_tx_buffer; - if (UARTDRV_InitUart(self->handle,&uartdrv_usart_init) + if (UARTDRV_InitUart(self->handle, &uartdrv_usart_init) != ECODE_EMDRV_UARTDRV_OK) { mp_raise_RuntimeError(translate("UART init")); } @@ -123,7 +123,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (receiver_buffer != NULL) { ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { - if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size)) { m_malloc_fail(receiver_buffer_size); } } @@ -183,7 +183,7 @@ void UARTDRV_Receive_Callback(UARTDRV_Handle_t *handle, taskENTER_CRITICAL(); ringbuf_put_n(&context->ringbuf, &context->rx_char, 1); taskEXIT_CRITICAL(); - errflag = UARTDRV_Receive(context->handle,&context->rx_char,1, + errflag = UARTDRV_Receive(context->handle, &context->rx_char, 1, (UARTDRV_Callback_t)UARTDRV_Receive_Callback); if (context->sigint_enabled) { if (context->rx_char == CHAR_CTRL_C) { @@ -213,7 +213,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, RUN_BACKGROUND_TASKS; // restart if it failed in the callback if (errflag != ECODE_EMDRV_UARTDRV_OK) { - errflag = UARTDRV_Receive(self->handle,&self->rx_char,1, + errflag = UARTDRV_Receive(self->handle, &self->rx_char, 1, (UARTDRV_Callback_t)UARTDRV_Receive_Callback); } // Allow user to break out of a timeout with a KeyboardInterrupt. diff --git a/ports/silabs/common-hal/digitalio/DigitalInOut.c b/ports/silabs/common-hal/digitalio/DigitalInOut.c index 0f266bb41e748..b673d392f216e 100644 --- a/ports/silabs/common-hal/digitalio/DigitalInOut.c +++ b/ports/silabs/common-hal/digitalio/DigitalInOut.c @@ -64,11 +64,11 @@ void common_hal_digitalio_digitalinout_deinit( digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { if (pull == PULL_NONE) { - GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeInput,1); + GPIO_PinModeSet(self->pin->port, self->pin->number, gpioModeInput, 1); } else if (pull == PULL_UP) { - GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeInputPull,1); + GPIO_PinModeSet(self->pin->port, self->pin->number, gpioModeInputPull, 1); } else { - GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeInputPull,0); + GPIO_PinModeSet(self->pin->port, self->pin->number, gpioModeInputPull, 0); } return DIGITALINOUT_OK; } @@ -78,11 +78,11 @@ digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( digitalio_digitalinout_obj_t *self, bool value, digitalio_drive_mode_t drive_mode) { if (drive_mode == DRIVE_MODE_OPEN_DRAIN) { - GPIO_PinModeSet(self->pin->port,self->pin->number, - gpioModeWiredAnd,value); + GPIO_PinModeSet(self->pin->port, self->pin->number, + gpioModeWiredAnd, value); } else { - GPIO_PinModeSet(self->pin->port,self->pin->number, - gpioModePushPull,value); + GPIO_PinModeSet(self->pin->port, self->pin->number, + gpioModePushPull, value); } if (value) { @@ -97,7 +97,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( // Get direction of the pin digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( digitalio_digitalinout_obj_t *self) { - GPIO_Mode_TypeDef mode = GPIO_PinModeGet(self->pin->port,self->pin->number); + GPIO_Mode_TypeDef mode = GPIO_PinModeGet(self->pin->port, self->pin->number); if (mode >= gpioModePushPull) { return DIRECTION_OUTPUT; } @@ -129,9 +129,9 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( digitalio_digitalinout_obj_t *self, digitalio_drive_mode_t drive_mode) { if (drive_mode == DRIVE_MODE_OPEN_DRAIN) { - GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModeWiredAnd,1); + GPIO_PinModeSet(self->pin->port, self->pin->number, gpioModeWiredAnd, 1); } else { - GPIO_PinModeSet(self->pin->port,self->pin->number,gpioModePushPull,1); + GPIO_PinModeSet(self->pin->port, self->pin->number, gpioModePushPull, 1); } return DIGITALINOUT_OK; } @@ -139,7 +139,7 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( // Get drive mode digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( digitalio_digitalinout_obj_t *self) { - GPIO_Mode_TypeDef mode = GPIO_PinModeGet(self->pin->port,self->pin->number); + GPIO_Mode_TypeDef mode = GPIO_PinModeGet(self->pin->port, self->pin->number); if (mode >= gpioModeWiredAnd) { return DRIVE_MODE_OPEN_DRAIN; } diff --git a/ports/silabs/common-hal/microcontroller/Pin.c b/ports/silabs/common-hal/microcontroller/Pin.c index 24141522df73a..d22485c40d642 100644 --- a/ports/silabs/common-hal/microcontroller/Pin.c +++ b/ports/silabs/common-hal/microcontroller/Pin.c @@ -47,9 +47,9 @@ void reset_all_pins(void) { for (port_num = 0; port_num < GPIO_PORT_COUNT; port_num++) { for (pin_num = 0; pin_num < 16; pin_num++) { - if (GPIO_PORT_PIN_VALID(ports[port_num],pin_num) + if (GPIO_PORT_PIN_VALID(ports[port_num], pin_num) && !(never_reset_pins[port_num] >> pin_num & 0x01)) { - GPIO_PinModeSet(ports[port_num], pin_num,gpioModeInput,1); + GPIO_PinModeSet(ports[port_num], pin_num, gpioModeInput, 1); } } } diff --git a/ports/silabs/license.md b/ports/silabs/license.md index 5b8797814f434..4833861a01637 100644 --- a/ports/silabs/license.md +++ b/ports/silabs/license.md @@ -1,4 +1,4 @@ -MIT License +The MIT License (MIT) Copyright (c) 2013-2022 Damien P. George and others diff --git a/ports/silabs/supervisor/internal_flash.c b/ports/silabs/supervisor/internal_flash.c index c260649c6318c..bb2b16726d30d 100644 --- a/ports/silabs/supervisor/internal_flash.c +++ b/ports/silabs/supervisor/internal_flash.c @@ -86,7 +86,7 @@ void port_internal_flash_flush(void) { reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); } taskENTER_CRITICAL(); - ret = MSC_WriteWord((uint32_t *)_flash_page_addr,_flash_cache,FLASH_PAGE_SIZE); + ret = MSC_WriteWord((uint32_t *)_flash_page_addr, _flash_cache, FLASH_PAGE_SIZE); taskEXIT_CRITICAL(); if (mscReturnOk != ret) { reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); diff --git a/ports/stm/Makefile b/ports/stm/Makefile index b9709d0c2ee1e..f8ac985ab97f7 100755 --- a/ports/stm/Makefile +++ b/ports/stm/Makefile @@ -291,8 +291,3 @@ flash: $(BUILD)/firmware.bin dfu-util -a 0 --dfuse-address $(BOOTLOADER_OFFSET) -D $(BUILD)/firmware.bin include $(TOP)/py/mkrules.mk - -# Print out the value of a make variable. -# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile -print-%: - @echo $* = $($*) diff --git a/ports/stm/common-hal/alarm/__init__.c b/ports/stm/common-hal/alarm/__init__.c index 78d50b41a8993..3d5f43a91a306 100644 --- a/ports/stm/common-hal/alarm/__init__.c +++ b/ports/stm/common-hal/alarm/__init__.c @@ -122,11 +122,11 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj stm_sleep_source_t cause = alarm_get_wakeup_cause(); switch (cause) { case STM_WAKEUP_RTC: { - wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms, alarms); break; } case STM_WAKEUP_GPIO: { - wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms,alarms); + wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms, alarms); break; } default: diff --git a/ports/stm/common-hal/alarm/pin/PinAlarm.c b/ports/stm/common-hal/alarm/pin/PinAlarm.c index 161bd9fea6174..fe1f595f88d43 100644 --- a/ports/stm/common-hal/alarm/pin/PinAlarm.c +++ b/ports/stm/common-hal/alarm/pin/PinAlarm.c @@ -147,7 +147,7 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob if (!stm_peripherals_exti_reserve(alarm->pin->number)) { mp_raise_RuntimeError(translate("Pin interrupt already in use")); } - stm_peripherals_exti_set_callback(pin_alarm_callback,alarm->pin->number); + stm_peripherals_exti_set_callback(pin_alarm_callback, alarm->pin->number); stm_peripherals_exti_enable(alarm->pin->number); reserved_alarms[alarm->pin->number] = true; } diff --git a/ports/stm/common-hal/alarm/time/TimeAlarm.c b/ports/stm/common-hal/alarm/time/TimeAlarm.c index 9ba6ed76585e5..e53b8160da766 100644 --- a/ports/stm/common-hal/alarm/time/TimeAlarm.c +++ b/ports/stm/common-hal/alarm/time/TimeAlarm.c @@ -108,15 +108,15 @@ void alarm_time_timealarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ // Use alarm B, since port reserves A // If true deep sleep is called, it will either ignore or overwrite this depending on // whether it is shorter or longer than the USB delay - stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B,timer_callback); - stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B,wakeup_in_ticks); + stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B, timer_callback); + stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B, wakeup_in_ticks); } void alarm_time_timealarm_prepare_for_deep_sleep(void) { if (deep_sleep_ticks) { // This is used for both fake and real deep sleep, so it still needs the callback - stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B,timer_callback); - stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B,deep_sleep_ticks); + stm32_peripherals_rtc_assign_alarm_callback(PERIPHERALS_ALARM_B, timer_callback); + stm32_peripherals_rtc_set_alarm(PERIPHERALS_ALARM_B, deep_sleep_ticks); deep_sleep_ticks = 0; } } diff --git a/ports/stm/common-hal/analogio/AnalogIn.c b/ports/stm/common-hal/analogio/AnalogIn.c index 7bed932c71a7d..6a67720970505 100644 --- a/ports/stm/common-hal/analogio/AnalogIn.c +++ b/ports/stm/common-hal/analogio/AnalogIn.c @@ -79,7 +79,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { if (common_hal_analogio_analogin_deinited(self)) { return; } - reset_pin_number(self->pin->port,self->pin->number); + reset_pin_number(self->pin->port, self->pin->number); self->pin = NULL; } @@ -200,7 +200,7 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { if (HAL_ADC_Start(&AdcHandle) != HAL_OK) { return 0; } - HAL_ADC_PollForConversion(&AdcHandle,1); + HAL_ADC_PollForConversion(&AdcHandle, 1); uint16_t value = (uint16_t)HAL_ADC_GetValue(&AdcHandle); HAL_ADC_Stop(&AdcHandle); diff --git a/ports/stm/common-hal/analogio/AnalogOut.c b/ports/stm/common-hal/analogio/AnalogOut.c index 4dd8783545e1c..129bb37266026 100644 --- a/ports/stm/common-hal/analogio/AnalogOut.c +++ b/ports/stm/common-hal/analogio/AnalogOut.c @@ -105,7 +105,7 @@ bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) { void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { #if HAS_DAC - reset_pin_number(self->pin->port,self->pin->number); + reset_pin_number(self->pin->port, self->pin->number); self->pin = NULL; dac_on[self->dac_index] = false; diff --git a/ports/stm/common-hal/audiopwmio/PWMAudioOut.c b/ports/stm/common-hal/audiopwmio/PWMAudioOut.c index d7df155932e89..00a1bce488295 100644 --- a/ports/stm/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/stm/common-hal/audiopwmio/PWMAudioOut.c @@ -284,10 +284,10 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, mp_raise_ValueError_varg(translate("Buffer length %d too big. It must be less than %d"), max_buffer_length, UINT16_MAX); } uint16_t buffer_length = (uint16_t)max_buffer_length / self->bytes_per_sample; - self->buffer[0] = m_malloc(buffer_length * sizeof(uint16_t), false); + self->buffer[0] = m_malloc(buffer_length * sizeof(uint16_t)); self->buffer_ptr[0] = self->buffer_length[0] = 0; if (self->pin[1]) { - self->buffer[1] = m_malloc(buffer_length * sizeof(uint16_t), false); + self->buffer[1] = m_malloc(buffer_length * sizeof(uint16_t)); self->buffer_ptr[1] = self->buffer_length[1] = 0; } diff --git a/ports/stm/common-hal/busio/I2C.c b/ports/stm/common-hal/busio/I2C.c index 42c32b2b5255c..d565bd16334c8 100644 --- a/ports/stm/common-hal/busio/I2C.c +++ b/ports/stm/common-hal/busio/I2C.c @@ -208,8 +208,8 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { reserved_i2c[self->sda->periph_index - 1] = false; never_reset_i2c[self->sda->periph_index - 1] = false; - reset_pin_number(self->sda->pin->port,self->sda->pin->number); - reset_pin_number(self->scl->pin->port,self->scl->pin->number); + reset_pin_number(self->sda->pin->port, self->sda->pin->number); + reset_pin_number(self->scl->pin->port, self->scl->pin->number); self->sda = NULL; self->scl = NULL; } diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c index 2fea1149eb96e..54905d9d1e97f 100644 --- a/ports/stm/common-hal/busio/SPI.c +++ b/ports/stm/common-hal/busio/SPI.c @@ -73,14 +73,14 @@ STATIC uint32_t get_busclock(SPI_TypeDef *instance) { STATIC uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t *prescaler, uint32_t busclock) { static const uint32_t baud_map[8][2] = { - {2,SPI_BAUDRATEPRESCALER_2}, - {4,SPI_BAUDRATEPRESCALER_4}, - {8,SPI_BAUDRATEPRESCALER_8}, - {16,SPI_BAUDRATEPRESCALER_16}, - {32,SPI_BAUDRATEPRESCALER_32}, - {64,SPI_BAUDRATEPRESCALER_64}, - {128,SPI_BAUDRATEPRESCALER_128}, - {256,SPI_BAUDRATEPRESCALER_256} + {2, SPI_BAUDRATEPRESCALER_2}, + {4, SPI_BAUDRATEPRESCALER_4}, + {8, SPI_BAUDRATEPRESCALER_8}, + {16, SPI_BAUDRATEPRESCALER_16}, + {32, SPI_BAUDRATEPRESCALER_32}, + {64, SPI_BAUDRATEPRESCALER_64}, + {128, SPI_BAUDRATEPRESCALER_128}, + {256, SPI_BAUDRATEPRESCALER_256} }; size_t i = 0; uint16_t divisor; @@ -267,12 +267,12 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { reserved_spi[self->sck->periph_index - 1] = false; never_reset_spi[self->sck->periph_index - 1] = false; - reset_pin_number(self->sck->pin->port,self->sck->pin->number); + reset_pin_number(self->sck->pin->port, self->sck->pin->number); if (self->mosi != NULL) { - reset_pin_number(self->mosi->pin->port,self->mosi->pin->number); + reset_pin_number(self->mosi->pin->port, self->mosi->pin->number); } if (self->miso != NULL) { - reset_pin_number(self->miso->pin->port,self->miso->pin->number); + reset_pin_number(self->miso->pin->port, self->miso->pin->number); } self->sck = NULL; self->mosi = NULL; @@ -379,7 +379,7 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, mp_raise_ValueError_varg(translate("No %q pin"), MP_QSTR_miso); } HAL_StatusTypeDef result = HAL_SPI_TransmitReceive(&self->handle, - (uint8_t *)data_out, data_in, (uint16_t)len,HAL_MAX_DELAY); + (uint8_t *)data_out, data_in, (uint16_t)len, HAL_MAX_DELAY); return result == HAL_OK; } diff --git a/ports/stm/common-hal/busio/UART.c b/ports/stm/common-hal/busio/UART.c index abf37ab881a08..5c9e05250af70 100644 --- a/ports/stm/common-hal/busio/UART.c +++ b/ports/stm/common-hal/busio/UART.c @@ -218,13 +218,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, if (receiver_buffer != NULL) { ringbuf_init(&self->ringbuf, receiver_buffer, receiver_buffer_size); } else { - // Initially allocate the UART's buffer in the long-lived part of the - // heap. UARTs are generally long-lived objects, but the "make long- - // lived" machinery is incapable of moving internal pointers like - // self->buffer, so do it manually. (However, as long as internal - // pointers like this are NOT moved, allocating the buffer - // in the long-lived pool is not strictly necessary) - if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) { + if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size)) { m_malloc_fail(receiver_buffer_size); } } @@ -280,11 +274,11 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { } if (self->tx) { - reset_pin_number(self->tx->pin->port,self->tx->pin->number); + reset_pin_number(self->tx->pin->port, self->tx->pin->number); self->tx = NULL; } if (self->rx) { - reset_pin_number(self->rx->pin->port,self->rx->pin->number); + reset_pin_number(self->rx->pin->port, self->rx->pin->number); self->rx = NULL; } diff --git a/ports/stm/common-hal/canio/Listener.c b/ports/stm/common-hal/canio/Listener.c index 0def8192f943e..36c138ddd2697 100644 --- a/ports/stm/common-hal/canio/Listener.c +++ b/ports/stm/common-hal/canio/Listener.c @@ -285,8 +285,8 @@ mp_obj_t common_hal_canio_listener_receive(canio_listener_obj_t *self) { uint32_t rdtr = self->mailbox->RDTR; bool rtr = rir & CAN_RI0R_RTR; - canio_message_obj_t *message = m_new_obj(canio_message_obj_t); - message->base.type = rtr ? &canio_remote_transmission_request_type : &canio_message_type; + canio_message_obj_t *message = + mp_obj_malloc(canio_message_obj_t, rtr ? &canio_remote_transmission_request_type : &canio_message_type); message->extended = rir & CAN_RI0R_IDE; if (message->extended) { message->id = rir >> 3; diff --git a/ports/stm/common-hal/digitalio/DigitalInOut.c b/ports/stm/common-hal/digitalio/DigitalInOut.c index 51b05907f7757..a57790cd1bec5 100644 --- a/ports/stm/common-hal/digitalio/DigitalInOut.c +++ b/ports/stm/common-hal/digitalio/DigitalInOut.c @@ -142,13 +142,13 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( switch (pull) { case PULL_UP: - LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number),LL_GPIO_PULL_UP); + LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number), LL_GPIO_PULL_UP); break; case PULL_DOWN: - LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number),LL_GPIO_PULL_DOWN); + LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number), LL_GPIO_PULL_DOWN); break; case PULL_NONE: - LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number),LL_GPIO_PULL_NO); + LL_GPIO_SetPinPull(pin_port(self->pin->port), pin_mask(self->pin->number), LL_GPIO_PULL_NO); break; default: break; diff --git a/ports/stm/common-hal/microcontroller/Processor.c b/ports/stm/common-hal/microcontroller/Processor.c index 8e21ca8d8283c..7b3e6a7232db6 100644 --- a/ports/stm/common-hal/microcontroller/Processor.c +++ b/ports/stm/common-hal/microcontroller/Processor.c @@ -86,7 +86,7 @@ float common_hal_mcu_processor_get_temperature(void) { HAL_ADC_ConfigChannel(&AdcHandle, &sConfig); HAL_ADC_Start(&AdcHandle); - if (HAL_ADC_PollForConversion(&AdcHandle,1) != HAL_OK) { + if (HAL_ADC_PollForConversion(&AdcHandle, 1) != HAL_OK) { mp_raise_RuntimeError(translate("Temperature read timed out")); } uint32_t value = (uint32_t)HAL_ADC_GetValue(&AdcHandle); @@ -118,7 +118,7 @@ float common_hal_mcu_processor_get_voltage(void) { HAL_ADC_ConfigChannel(&AdcHandle, &sConfig); HAL_ADC_Start(&AdcHandle); - if (HAL_ADC_PollForConversion(&AdcHandle,1) != HAL_OK) { + if (HAL_ADC_PollForConversion(&AdcHandle, 1) != HAL_OK) { mp_raise_RuntimeError(translate("Voltage read timed out")); } uint32_t value = (uint32_t)HAL_ADC_GetValue(&AdcHandle); diff --git a/ports/stm/common-hal/os/__init__.c b/ports/stm/common-hal/os/__init__.c index 66dfd9f768428..fccaa00bcd0e2 100644 --- a/ports/stm/common-hal/os/__init__.c +++ b/ports/stm/common-hal/os/__init__.c @@ -79,7 +79,7 @@ bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { uint32_t new_random; uint32_t start = HAL_GetTick(); // the HAL function has a timeout, but it isn't long enough, and isn't adjustable - while (!(__HAL_RNG_GET_FLAG(&handle,RNG_FLAG_DRDY)) && ((HAL_GetTick() - start) < RNG_TIMEOUT)) { + while (!(__HAL_RNG_GET_FLAG(&handle, RNG_FLAG_DRDY)) && ((HAL_GetTick() - start) < RNG_TIMEOUT)) { ; } if (HAL_RNG_GenerateRandomNumber(&handle, &new_random) != HAL_OK) { diff --git a/ports/stm/common-hal/pulseio/PulseIn.c b/ports/stm/common-hal/pulseio/PulseIn.c index 5b7602d9bf7db..0754130e17992 100644 --- a/ports/stm/common-hal/pulseio/PulseIn.c +++ b/ports/stm/common-hal/pulseio/PulseIn.c @@ -120,7 +120,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu } // Allocate pulse buffer - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t), false); + self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { // TODO: free the EXTI here? m_malloc_fail(maxlen * sizeof(uint16_t)); diff --git a/ports/stm/common-hal/sdioio/SDCard.c b/ports/stm/common-hal/sdioio/SDCard.c index 6f3eb682df8a7..5297c477481a5 100644 --- a/ports/stm/common-hal/sdioio/SDCard.c +++ b/ports/stm/common-hal/sdioio/SDCard.c @@ -269,13 +269,13 @@ bool common_hal_sdioio_sdcard_deinited(sdioio_sdcard_obj_t *self) { STATIC void never_reset_mcu_periph(const mcu_periph_obj_t *periph) { if (periph) { - never_reset_pin_number(periph->pin->port,periph->pin->number); + never_reset_pin_number(periph->pin->port, periph->pin->number); } } STATIC void reset_mcu_periph(const mcu_periph_obj_t *periph) { if (periph) { - reset_pin_number(periph->pin->port,periph->pin->number); + reset_pin_number(periph->pin->port, periph->pin->number); } } diff --git a/ports/stm/peripherals/stm32f4/stm32f401xe/gpio.c b/ports/stm/peripherals/stm32f4/stm32f401xe/gpio.c index 86634cf6c2d94..a7e01b70e9a27 100644 --- a/ports/stm/peripherals/stm32f4/stm32f401xe/gpio.c +++ b/ports/stm/peripherals/stm32f4/stm32f401xe/gpio.c @@ -37,8 +37,8 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOH_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK } diff --git a/ports/stm/peripherals/stm32f4/stm32f401xe/periph.c b/ports/stm/peripherals/stm32f4/stm32f401xe/periph.c index 23664999b0e60..582a3f27ca308 100644 --- a/ports/stm/peripherals/stm32f4/stm32f401xe/periph.c +++ b/ports/stm/peripherals/stm32f4/stm32f401xe/periph.c @@ -127,47 +127,47 @@ TIM_TypeDef *mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, NULL // #define TIM(index, alt, channel, tim_pin) const mcu_tim_pin_obj_t mcu_tim_pin_list[44] = { - TIM(2,1,1,&pin_PA00), - TIM(5,2,1,&pin_PA00), - TIM(2,1,2,&pin_PA01), - TIM(5,2,2,&pin_PA01), - TIM(2,1,3,&pin_PA02), - TIM(5,2,3,&pin_PA02), - TIM(2,1,4,&pin_PA03), - TIM(5,2,4,&pin_PA03), - TIM(9,3,1,&pin_PA02), - TIM(9,3,2,&pin_PA03), - TIM(3,2,1,&pin_PA06), - TIM(3,2,2,&pin_PA07), - TIM(1,1,1,&pin_PA08), - TIM(1,1,2,&pin_PA09), - TIM(1,1,3,&pin_PA10), - TIM(1,1,4,&pin_PA11), - TIM(2,1,1,&pin_PA15), - TIM(3,2,3,&pin_PB00), - TIM(3,2,4,&pin_PB01), - TIM(2,1,2,&pin_PB03), - TIM(3,2,1,&pin_PB04), - TIM(3,2,2,&pin_PB05), - TIM(4,2,1,&pin_PB06), - TIM(4,2,2,&pin_PB07), - TIM(4,2,3,&pin_PB08), - TIM(10,2,1,&pin_PB08), - TIM(4,2,4,&pin_PB09), - TIM(11,2,1,&pin_PB09), - TIM(2,1,3,&pin_PB10), - TIM(3,2,1,&pin_PC06), - TIM(3,2,2,&pin_PC07), - TIM(3,2,3,&pin_PC08), - TIM(3,2,4,&pin_PC09), - TIM(4,2,1,&pin_PD12), - TIM(4,2,2,&pin_PD13), - TIM(4,2,3,&pin_PD14), - TIM(4,2,4,&pin_PD15), - TIM(9,3,1,&pin_PE05), - TIM(9,3,2,&pin_PE06), - TIM(1,1,1,&pin_PE09), - TIM(1,1,2,&pin_PE11), - TIM(1,1,3,&pin_PE13), - TIM(1,1,4,&pin_PE14), + TIM(2, 1, 1, &pin_PA00), + TIM(5, 2, 1, &pin_PA00), + TIM(2, 1, 2, &pin_PA01), + TIM(5, 2, 2, &pin_PA01), + TIM(2, 1, 3, &pin_PA02), + TIM(5, 2, 3, &pin_PA02), + TIM(2, 1, 4, &pin_PA03), + TIM(5, 2, 4, &pin_PA03), + TIM(9, 3, 1, &pin_PA02), + TIM(9, 3, 2, &pin_PA03), + TIM(3, 2, 1, &pin_PA06), + TIM(3, 2, 2, &pin_PA07), + TIM(1, 1, 1, &pin_PA08), + TIM(1, 1, 2, &pin_PA09), + TIM(1, 1, 3, &pin_PA10), + TIM(1, 1, 4, &pin_PA11), + TIM(2, 1, 1, &pin_PA15), + TIM(3, 2, 3, &pin_PB00), + TIM(3, 2, 4, &pin_PB01), + TIM(2, 1, 2, &pin_PB03), + TIM(3, 2, 1, &pin_PB04), + TIM(3, 2, 2, &pin_PB05), + TIM(4, 2, 1, &pin_PB06), + TIM(4, 2, 2, &pin_PB07), + TIM(4, 2, 3, &pin_PB08), + TIM(10, 2, 1, &pin_PB08), + TIM(4, 2, 4, &pin_PB09), + TIM(11, 2, 1, &pin_PB09), + TIM(2, 1, 3, &pin_PB10), + TIM(3, 2, 1, &pin_PC06), + TIM(3, 2, 2, &pin_PC07), + TIM(3, 2, 3, &pin_PC08), + TIM(3, 2, 4, &pin_PC09), + TIM(4, 2, 1, &pin_PD12), + TIM(4, 2, 2, &pin_PD13), + TIM(4, 2, 3, &pin_PD14), + TIM(4, 2, 4, &pin_PD15), + TIM(9, 3, 1, &pin_PE05), + TIM(9, 3, 2, &pin_PE06), + TIM(1, 1, 1, &pin_PE09), + TIM(1, 1, 2, &pin_PE11), + TIM(1, 1, 3, &pin_PE13), + TIM(1, 1, 4, &pin_PE14), }; diff --git a/ports/stm/peripherals/stm32f4/stm32f401xe/pins.c b/ports/stm/peripherals/stm32f4/stm32f401xe/pins.c index a155970bb075b..8593fc1517462 100644 --- a/ports/stm/peripherals/stm32f4/stm32f401xe/pins.c +++ b/ports/stm/peripherals/stm32f4/stm32f401xe/pins.c @@ -38,25 +38,25 @@ const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); // anti-tamp const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); // OSC32_IN const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); // OSC32_OUT -const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1,10)); -const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1,11)); -const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1,12)); -const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1,13)); - -const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,0)); -const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,1)); -const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,2)); -const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,3)); -const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,4)); -const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,5)); -const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,6)); -const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,7)); - -const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1,14)); -const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1,15)); - -const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,8)); -const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,9)); +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1, 10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1, 11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1, 12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1, 13)); + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1, 2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1, 3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1, 4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1, 5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1, 6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1, 7)); + +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1, 14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1, 15)); + +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1, 8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1, 9)); const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC); diff --git a/ports/stm/peripherals/stm32f4/stm32f405xx/gpio.c b/ports/stm/peripherals/stm32f4/stm32f405xx/gpio.c index 3857666232f50..dda96d57dabde 100644 --- a/ports/stm/peripherals/stm32f4/stm32f405xx/gpio.c +++ b/ports/stm/peripherals/stm32f4/stm32f405xx/gpio.c @@ -38,11 +38,11 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOG_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,13); // PC13 anti tamp - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(2, 13); // PC13 anti tamp + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK // never_reset_pin_number(0,15); //PA15 JTDI // never_reset_pin_number(1,3); //PB3 JTDO // never_reset_pin_number(1,4); //PB4 JTRST diff --git a/ports/stm/peripherals/stm32f4/stm32f405xx/pins.c b/ports/stm/peripherals/stm32f4/stm32f405xx/pins.c index 9fef433ea28e9..0f519a9b82463 100644 --- a/ports/stm/peripherals/stm32f4/stm32f405xx/pins.c +++ b/ports/stm/peripherals/stm32f4/stm32f405xx/pins.c @@ -28,14 +28,14 @@ #include "py/mphal.h" #include "peripherals/pins.h" -const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_123,0)); -const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_123,1)); -const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_123,2)); -const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_123,3)); -const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_12,4)); -const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_12,5)); -const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_12,6)); -const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_12,7)); +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_123, 0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_123, 1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_123, 2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_123, 3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_12, 4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_12, 5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_12, 6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_12, 7)); const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); @@ -44,8 +44,8 @@ const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); -const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_12,8)); -const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_12,9)); +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_12, 8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_12, 9)); const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); @@ -60,12 +60,12 @@ const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); -const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_123,10)); -const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_123,11)); -const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_123,12)); -const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_123,13)); -const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_12,14)); -const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_12,15)); +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_123, 10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_123, 11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_123, 12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_123, 13)); +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_12, 14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_12, 15)); const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); @@ -111,14 +111,14 @@ const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC); const mcu_pin_obj_t pin_PF00 = PIN(5, 0, NO_ADC); const mcu_pin_obj_t pin_PF01 = PIN(5, 1, NO_ADC); const mcu_pin_obj_t pin_PF02 = PIN(5, 2, NO_ADC); -const mcu_pin_obj_t pin_PF03 = PIN(5, 3, ADC_INPUT(ADC_3,9)); -const mcu_pin_obj_t pin_PF04 = PIN(5, 4, ADC_INPUT(ADC_3,14)); -const mcu_pin_obj_t pin_PF05 = PIN(5, 5, ADC_INPUT(ADC_3,15)); -const mcu_pin_obj_t pin_PF06 = PIN(5, 6, ADC_INPUT(ADC_3,4)); -const mcu_pin_obj_t pin_PF07 = PIN(5, 7, ADC_INPUT(ADC_3,5)); -const mcu_pin_obj_t pin_PF08 = PIN(5, 8, ADC_INPUT(ADC_3,6)); -const mcu_pin_obj_t pin_PF09 = PIN(5, 9, ADC_INPUT(ADC_3,7)); -const mcu_pin_obj_t pin_PF10 = PIN(5, 10, ADC_INPUT(ADC_3,8)); +const mcu_pin_obj_t pin_PF03 = PIN(5, 3, ADC_INPUT(ADC_3, 9)); +const mcu_pin_obj_t pin_PF04 = PIN(5, 4, ADC_INPUT(ADC_3, 14)); +const mcu_pin_obj_t pin_PF05 = PIN(5, 5, ADC_INPUT(ADC_3, 15)); +const mcu_pin_obj_t pin_PF06 = PIN(5, 6, ADC_INPUT(ADC_3, 4)); +const mcu_pin_obj_t pin_PF07 = PIN(5, 7, ADC_INPUT(ADC_3, 5)); +const mcu_pin_obj_t pin_PF08 = PIN(5, 8, ADC_INPUT(ADC_3, 6)); +const mcu_pin_obj_t pin_PF09 = PIN(5, 9, ADC_INPUT(ADC_3, 7)); +const mcu_pin_obj_t pin_PF10 = PIN(5, 10, ADC_INPUT(ADC_3, 8)); const mcu_pin_obj_t pin_PF11 = PIN(5, 11, NO_ADC); const mcu_pin_obj_t pin_PF12 = PIN(5, 12, NO_ADC); const mcu_pin_obj_t pin_PF13 = PIN(5, 13, NO_ADC); diff --git a/ports/stm/peripherals/stm32f4/stm32f407xx/gpio.c b/ports/stm/peripherals/stm32f4/stm32f407xx/gpio.c index 3857666232f50..dda96d57dabde 100644 --- a/ports/stm/peripherals/stm32f4/stm32f407xx/gpio.c +++ b/ports/stm/peripherals/stm32f4/stm32f407xx/gpio.c @@ -38,11 +38,11 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOG_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,13); // PC13 anti tamp - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(2, 13); // PC13 anti tamp + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK // never_reset_pin_number(0,15); //PA15 JTDI // never_reset_pin_number(1,3); //PB3 JTDO // never_reset_pin_number(1,4); //PB4 JTRST diff --git a/ports/stm/peripherals/stm32f4/stm32f407xx/pins.c b/ports/stm/peripherals/stm32f4/stm32f407xx/pins.c index 9fef433ea28e9..0f519a9b82463 100644 --- a/ports/stm/peripherals/stm32f4/stm32f407xx/pins.c +++ b/ports/stm/peripherals/stm32f4/stm32f407xx/pins.c @@ -28,14 +28,14 @@ #include "py/mphal.h" #include "peripherals/pins.h" -const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_123,0)); -const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_123,1)); -const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_123,2)); -const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_123,3)); -const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_12,4)); -const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_12,5)); -const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_12,6)); -const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_12,7)); +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_123, 0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_123, 1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_123, 2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_123, 3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_12, 4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_12, 5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_12, 6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_12, 7)); const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); @@ -44,8 +44,8 @@ const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); -const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_12,8)); -const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_12,9)); +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_12, 8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_12, 9)); const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); @@ -60,12 +60,12 @@ const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); -const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_123,10)); -const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_123,11)); -const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_123,12)); -const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_123,13)); -const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_12,14)); -const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_12,15)); +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_123, 10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_123, 11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_123, 12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_123, 13)); +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_12, 14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_12, 15)); const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); @@ -111,14 +111,14 @@ const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC); const mcu_pin_obj_t pin_PF00 = PIN(5, 0, NO_ADC); const mcu_pin_obj_t pin_PF01 = PIN(5, 1, NO_ADC); const mcu_pin_obj_t pin_PF02 = PIN(5, 2, NO_ADC); -const mcu_pin_obj_t pin_PF03 = PIN(5, 3, ADC_INPUT(ADC_3,9)); -const mcu_pin_obj_t pin_PF04 = PIN(5, 4, ADC_INPUT(ADC_3,14)); -const mcu_pin_obj_t pin_PF05 = PIN(5, 5, ADC_INPUT(ADC_3,15)); -const mcu_pin_obj_t pin_PF06 = PIN(5, 6, ADC_INPUT(ADC_3,4)); -const mcu_pin_obj_t pin_PF07 = PIN(5, 7, ADC_INPUT(ADC_3,5)); -const mcu_pin_obj_t pin_PF08 = PIN(5, 8, ADC_INPUT(ADC_3,6)); -const mcu_pin_obj_t pin_PF09 = PIN(5, 9, ADC_INPUT(ADC_3,7)); -const mcu_pin_obj_t pin_PF10 = PIN(5, 10, ADC_INPUT(ADC_3,8)); +const mcu_pin_obj_t pin_PF03 = PIN(5, 3, ADC_INPUT(ADC_3, 9)); +const mcu_pin_obj_t pin_PF04 = PIN(5, 4, ADC_INPUT(ADC_3, 14)); +const mcu_pin_obj_t pin_PF05 = PIN(5, 5, ADC_INPUT(ADC_3, 15)); +const mcu_pin_obj_t pin_PF06 = PIN(5, 6, ADC_INPUT(ADC_3, 4)); +const mcu_pin_obj_t pin_PF07 = PIN(5, 7, ADC_INPUT(ADC_3, 5)); +const mcu_pin_obj_t pin_PF08 = PIN(5, 8, ADC_INPUT(ADC_3, 6)); +const mcu_pin_obj_t pin_PF09 = PIN(5, 9, ADC_INPUT(ADC_3, 7)); +const mcu_pin_obj_t pin_PF10 = PIN(5, 10, ADC_INPUT(ADC_3, 8)); const mcu_pin_obj_t pin_PF11 = PIN(5, 11, NO_ADC); const mcu_pin_obj_t pin_PF12 = PIN(5, 12, NO_ADC); const mcu_pin_obj_t pin_PF13 = PIN(5, 13, NO_ADC); diff --git a/ports/stm/peripherals/stm32f4/stm32f411xe/gpio.c b/ports/stm/peripherals/stm32f4/stm32f411xe/gpio.c index 351607a70eb5b..e63e46d3189a1 100644 --- a/ports/stm/peripherals/stm32f4/stm32f411xe/gpio.c +++ b/ports/stm/peripherals/stm32f4/stm32f411xe/gpio.c @@ -40,12 +40,12 @@ void stm32_peripherals_gpio_init(void) { // Never reset pins // TODO: Move this out of peripherals. These helpers shouldn't reference anything CircuitPython // specific. - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT #if !(BOARD_OVERWRITE_SWD) - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK #endif // Port H is not included in GPIO port array diff --git a/ports/stm/peripherals/stm32f4/stm32f411xe/periph.c b/ports/stm/peripherals/stm32f4/stm32f411xe/periph.c index dd9cb3d842454..c47ecff271c66 100644 --- a/ports/stm/peripherals/stm32f4/stm32f411xe/periph.c +++ b/ports/stm/peripherals/stm32f4/stm32f411xe/periph.c @@ -148,47 +148,47 @@ TIM_TypeDef *mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, NULL TIM11, NULL, NULL, NULL}; const mcu_tim_pin_obj_t mcu_tim_pin_list[44] = { - TIM(2,1,1,&pin_PA00), - TIM(5,2,1,&pin_PA00), - TIM(2,1,2,&pin_PA01), - TIM(5,2,2,&pin_PA01), - TIM(2,1,3,&pin_PA02), - TIM(5,2,3,&pin_PA02), - TIM(2,1,4,&pin_PA03), - TIM(5,2,4,&pin_PA03), - TIM(9,3,1,&pin_PA02), - TIM(9,3,2,&pin_PA03), - TIM(3,2,1,&pin_PA06), - TIM(3,2,2,&pin_PA07), - TIM(1,1,1,&pin_PA08), - TIM(1,1,2,&pin_PA09), - TIM(1,1,3,&pin_PA10), - TIM(1,1,4,&pin_PA11), - TIM(2,1,1,&pin_PA15), - TIM(3,2,3,&pin_PB00), - TIM(3,2,4,&pin_PB01), - TIM(2,1,2,&pin_PB03), - TIM(3,2,1,&pin_PB04), - TIM(3,2,2,&pin_PB05), - TIM(4,2,1,&pin_PB06), - TIM(4,2,2,&pin_PB07), - TIM(4,2,3,&pin_PB08), - TIM(10,2,1,&pin_PB08), - TIM(4,2,4,&pin_PB09), - TIM(11,2,1,&pin_PB09), - TIM(2,1,3,&pin_PB10), - TIM(3,2,1,&pin_PC06), - TIM(3,2,2,&pin_PC07), - TIM(3,2,3,&pin_PC08), - TIM(3,2,4,&pin_PC09), - TIM(4,2,1,&pin_PD12), - TIM(4,2,2,&pin_PD13), - TIM(4,2,3,&pin_PD14), - TIM(4,2,4,&pin_PD15), - TIM(9,3,1,&pin_PE05), - TIM(9,3,2,&pin_PE06), - TIM(1,1,1,&pin_PE09), - TIM(1,1,2,&pin_PE11), - TIM(1,1,3,&pin_PE13), - TIM(1,1,4,&pin_PE14), + TIM(2, 1, 1, &pin_PA00), + TIM(5, 2, 1, &pin_PA00), + TIM(2, 1, 2, &pin_PA01), + TIM(5, 2, 2, &pin_PA01), + TIM(2, 1, 3, &pin_PA02), + TIM(5, 2, 3, &pin_PA02), + TIM(2, 1, 4, &pin_PA03), + TIM(5, 2, 4, &pin_PA03), + TIM(9, 3, 1, &pin_PA02), + TIM(9, 3, 2, &pin_PA03), + TIM(3, 2, 1, &pin_PA06), + TIM(3, 2, 2, &pin_PA07), + TIM(1, 1, 1, &pin_PA08), + TIM(1, 1, 2, &pin_PA09), + TIM(1, 1, 3, &pin_PA10), + TIM(1, 1, 4, &pin_PA11), + TIM(2, 1, 1, &pin_PA15), + TIM(3, 2, 3, &pin_PB00), + TIM(3, 2, 4, &pin_PB01), + TIM(2, 1, 2, &pin_PB03), + TIM(3, 2, 1, &pin_PB04), + TIM(3, 2, 2, &pin_PB05), + TIM(4, 2, 1, &pin_PB06), + TIM(4, 2, 2, &pin_PB07), + TIM(4, 2, 3, &pin_PB08), + TIM(10, 2, 1, &pin_PB08), + TIM(4, 2, 4, &pin_PB09), + TIM(11, 2, 1, &pin_PB09), + TIM(2, 1, 3, &pin_PB10), + TIM(3, 2, 1, &pin_PC06), + TIM(3, 2, 2, &pin_PC07), + TIM(3, 2, 3, &pin_PC08), + TIM(3, 2, 4, &pin_PC09), + TIM(4, 2, 1, &pin_PD12), + TIM(4, 2, 2, &pin_PD13), + TIM(4, 2, 3, &pin_PD14), + TIM(4, 2, 4, &pin_PD15), + TIM(9, 3, 1, &pin_PE05), + TIM(9, 3, 2, &pin_PE06), + TIM(1, 1, 1, &pin_PE09), + TIM(1, 1, 2, &pin_PE11), + TIM(1, 1, 3, &pin_PE13), + TIM(1, 1, 4, &pin_PE14), }; diff --git a/ports/stm/peripherals/stm32f4/stm32f411xe/pins.c b/ports/stm/peripherals/stm32f4/stm32f411xe/pins.c index a155970bb075b..8593fc1517462 100644 --- a/ports/stm/peripherals/stm32f4/stm32f411xe/pins.c +++ b/ports/stm/peripherals/stm32f4/stm32f411xe/pins.c @@ -38,25 +38,25 @@ const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); // anti-tamp const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); // OSC32_IN const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); // OSC32_OUT -const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1,10)); -const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1,11)); -const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1,12)); -const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1,13)); - -const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,0)); -const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,1)); -const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,2)); -const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,3)); -const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,4)); -const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,5)); -const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,6)); -const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,7)); - -const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1,14)); -const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1,15)); - -const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,8)); -const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,9)); +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1, 10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1, 11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1, 12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1, 13)); + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1, 2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1, 3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1, 4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1, 5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1, 6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1, 7)); + +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1, 14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1, 15)); + +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1, 8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1, 9)); const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC); diff --git a/ports/stm/peripherals/stm32f4/stm32f412cx/gpio.c b/ports/stm/peripherals/stm32f4/stm32f412cx/gpio.c index f55b63f296c14..f686dc3b463e0 100644 --- a/ports/stm/peripherals/stm32f4/stm32f412cx/gpio.c +++ b/ports/stm/peripherals/stm32f4/stm32f412cx/gpio.c @@ -34,6 +34,6 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK } diff --git a/ports/stm/peripherals/stm32f4/stm32f412cx/pins.c b/ports/stm/peripherals/stm32f4/stm32f412cx/pins.c index 57abacc99ad35..45c196ac6b28a 100644 --- a/ports/stm/peripherals/stm32f4/stm32f412cx/pins.c +++ b/ports/stm/peripherals/stm32f4/stm32f412cx/pins.c @@ -28,14 +28,14 @@ #include "py/mphal.h" #include "peripherals/pins.h" -const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,0)); -const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,1)); -const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,2)); -const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,3)); -const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,4)); -const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,5)); -const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,6)); -const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,7)); +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1, 2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1, 3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1, 4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1, 5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1, 6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1, 7)); const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); @@ -45,8 +45,8 @@ const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); -const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,8)); -const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,9)); +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1, 8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1, 9)); const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); diff --git a/ports/stm/peripherals/stm32f4/stm32f412zx/gpio.c b/ports/stm/peripherals/stm32f4/stm32f412zx/gpio.c index 6fe7bbb9c7b3b..13a7aca4af5e5 100644 --- a/ports/stm/peripherals/stm32f4/stm32f412zx/gpio.c +++ b/ports/stm/peripherals/stm32f4/stm32f412zx/gpio.c @@ -39,11 +39,11 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOD_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,13); // PC13 anti tamp - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(2, 13); // PC13 anti tamp + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK // never_reset_pin_number(0,15); //PA15 JTDI // never_reset_pin_number(1,3); //PB3 JTDO // never_reset_pin_number(1,4); //PB4 JTRST diff --git a/ports/stm/peripherals/stm32f4/stm32f412zx/periph.c b/ports/stm/peripherals/stm32f4/stm32f412zx/periph.c index 8cd61fd49d0fd..2e1c3114ef61b 100644 --- a/ports/stm/peripherals/stm32f4/stm32f412zx/periph.c +++ b/ports/stm/peripherals/stm32f4/stm32f412zx/periph.c @@ -160,64 +160,64 @@ TIM_TypeDef *mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, TIM8 TIM11, TIM12, TIM13, TIM14}; const mcu_tim_pin_obj_t mcu_tim_pin_list[60] = { - TIM(2,1,1,&pin_PA00), - TIM(5,2,1,&pin_PA00), - TIM(2,1,2,&pin_PA01), - TIM(5,2,2,&pin_PA01), - TIM(2,1,3,&pin_PA02), - TIM(5,2,3,&pin_PA02), - TIM(2,1,4,&pin_PA03), - TIM(5,2,4,&pin_PA03), - TIM(9,3,1,&pin_PA02), - TIM(9,3,2,&pin_PA03), - TIM(3,2,1,&pin_PA06), - TIM(13,9,1,&pin_PA06), - TIM(3,2,2,&pin_PA07), - TIM(14,9,1,&pin_PA07), - TIM(1,1,1,&pin_PA08), - TIM(1,1,2,&pin_PA09), - TIM(1,1,3,&pin_PA10), - TIM(1,1,4,&pin_PA11), - TIM(2,1,1,&pin_PA15), - TIM(3,2,3,&pin_PB00), - TIM(3,2,4,&pin_PB01), - TIM(2,1,2,&pin_PB03), - TIM(3,2,1,&pin_PB04), - TIM(3,2,2,&pin_PB05), - TIM(4,2,1,&pin_PB06), - TIM(4,2,2,&pin_PB07), - TIM(4,2,3,&pin_PB08), - TIM(10,2,1,&pin_PB08), - TIM(4,2,4,&pin_PB09), - TIM(11,2,1,&pin_PB09), - TIM(2,1,3,&pin_PB10), - TIM(2,1,4,&pin_PB11), - TIM(12,9,1,&pin_PB14), - TIM(12,9,2,&pin_PB15), - TIM(3,2,1,&pin_PC06), - TIM(3,2,2,&pin_PC07), - TIM(3,2,3,&pin_PC08), - TIM(3,2,4,&pin_PC09), - TIM(8,3,1,&pin_PC06), - TIM(8,3,2,&pin_PC07), - TIM(8,3,3,&pin_PC08), - TIM(8,3,4,&pin_PC09), - TIM(4,2,1,&pin_PD12), - TIM(4,2,2,&pin_PD13), - TIM(4,2,3,&pin_PD14), - TIM(4,2,4,&pin_PD15), - TIM(9,3,1,&pin_PE05), - TIM(9,3,2,&pin_PE06), - TIM(1,1,1,&pin_PE09), - TIM(1,1,2,&pin_PE11), - TIM(1,1,3,&pin_PE13), - TIM(1,1,4,&pin_PE14), - TIM(10,3,1,&pin_PF06), - TIM(11,3,1,&pin_PF07), - TIM(13,9,1,&pin_PF08), - TIM(14,9,1,&pin_PF09), - TIM(5,2,1,&pin_PF03), - TIM(5,2,2,&pin_PF04), - TIM(5,2,3,&pin_PF05), - TIM(5,2,4,&pin_PF10), + TIM(2, 1, 1, &pin_PA00), + TIM(5, 2, 1, &pin_PA00), + TIM(2, 1, 2, &pin_PA01), + TIM(5, 2, 2, &pin_PA01), + TIM(2, 1, 3, &pin_PA02), + TIM(5, 2, 3, &pin_PA02), + TIM(2, 1, 4, &pin_PA03), + TIM(5, 2, 4, &pin_PA03), + TIM(9, 3, 1, &pin_PA02), + TIM(9, 3, 2, &pin_PA03), + TIM(3, 2, 1, &pin_PA06), + TIM(13, 9, 1, &pin_PA06), + TIM(3, 2, 2, &pin_PA07), + TIM(14, 9, 1, &pin_PA07), + TIM(1, 1, 1, &pin_PA08), + TIM(1, 1, 2, &pin_PA09), + TIM(1, 1, 3, &pin_PA10), + TIM(1, 1, 4, &pin_PA11), + TIM(2, 1, 1, &pin_PA15), + TIM(3, 2, 3, &pin_PB00), + TIM(3, 2, 4, &pin_PB01), + TIM(2, 1, 2, &pin_PB03), + TIM(3, 2, 1, &pin_PB04), + TIM(3, 2, 2, &pin_PB05), + TIM(4, 2, 1, &pin_PB06), + TIM(4, 2, 2, &pin_PB07), + TIM(4, 2, 3, &pin_PB08), + TIM(10, 2, 1, &pin_PB08), + TIM(4, 2, 4, &pin_PB09), + TIM(11, 2, 1, &pin_PB09), + TIM(2, 1, 3, &pin_PB10), + TIM(2, 1, 4, &pin_PB11), + TIM(12, 9, 1, &pin_PB14), + TIM(12, 9, 2, &pin_PB15), + TIM(3, 2, 1, &pin_PC06), + TIM(3, 2, 2, &pin_PC07), + TIM(3, 2, 3, &pin_PC08), + TIM(3, 2, 4, &pin_PC09), + TIM(8, 3, 1, &pin_PC06), + TIM(8, 3, 2, &pin_PC07), + TIM(8, 3, 3, &pin_PC08), + TIM(8, 3, 4, &pin_PC09), + TIM(4, 2, 1, &pin_PD12), + TIM(4, 2, 2, &pin_PD13), + TIM(4, 2, 3, &pin_PD14), + TIM(4, 2, 4, &pin_PD15), + TIM(9, 3, 1, &pin_PE05), + TIM(9, 3, 2, &pin_PE06), + TIM(1, 1, 1, &pin_PE09), + TIM(1, 1, 2, &pin_PE11), + TIM(1, 1, 3, &pin_PE13), + TIM(1, 1, 4, &pin_PE14), + TIM(10, 3, 1, &pin_PF06), + TIM(11, 3, 1, &pin_PF07), + TIM(13, 9, 1, &pin_PF08), + TIM(14, 9, 1, &pin_PF09), + TIM(5, 2, 1, &pin_PF03), + TIM(5, 2, 2, &pin_PF04), + TIM(5, 2, 3, &pin_PF05), + TIM(5, 2, 4, &pin_PF10), }; diff --git a/ports/stm/peripherals/stm32f4/stm32f412zx/pins.c b/ports/stm/peripherals/stm32f4/stm32f412zx/pins.c index 4fa70b5bd84cc..c0ee9e99e47ed 100644 --- a/ports/stm/peripherals/stm32f4/stm32f412zx/pins.c +++ b/ports/stm/peripherals/stm32f4/stm32f412zx/pins.c @@ -50,25 +50,25 @@ const mcu_pin_obj_t pin_PF08 = PIN(5, 8, NO_ADC); // 144 only const mcu_pin_obj_t pin_PF09 = PIN(5, 9, NO_ADC); // 144 only const mcu_pin_obj_t pin_PF10 = PIN(5, 10, NO_ADC); // 144 only -const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1,10)); -const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1,11)); -const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1,12)); -const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1,13)); - -const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,0)); -const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,1)); -const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,2)); -const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,3)); -const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,4)); -const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,5)); -const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,6)); -const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,7)); - -const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1,14)); -const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1,15)); - -const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,8)); -const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,9)); +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1, 10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1, 11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1, 12)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1, 13)); + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 0)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 1)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1, 2)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1, 3)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1, 4)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1, 5)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1, 6)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1, 7)); + +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1, 14)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1, 15)); + +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1, 8)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1, 9)); const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); const mcu_pin_obj_t pin_PF11 = PIN(5, 11, NO_ADC); // 144 only diff --git a/ports/stm/peripherals/stm32f7/stm32f746xx/gpio.c b/ports/stm/peripherals/stm32f7/stm32f746xx/gpio.c index b7cc0aad6ecd3..7a6059eebc4e4 100644 --- a/ports/stm/peripherals/stm32f7/stm32f746xx/gpio.c +++ b/ports/stm/peripherals/stm32f7/stm32f746xx/gpio.c @@ -43,10 +43,10 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOK_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK - never_reset_pin_number(7,0); // PH0 OSC_IN - never_reset_pin_number(7,1); // PH1 OSC_OUT + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK + never_reset_pin_number(7, 0); // PH0 OSC_IN + never_reset_pin_number(7, 1); // PH1 OSC_OUT } diff --git a/ports/stm/peripherals/stm32f7/stm32f767xx/gpio.c b/ports/stm/peripherals/stm32f7/stm32f767xx/gpio.c index f89af2714eb57..8b5fa5f3e1c64 100644 --- a/ports/stm/peripherals/stm32f7/stm32f767xx/gpio.c +++ b/ports/stm/peripherals/stm32f7/stm32f767xx/gpio.c @@ -39,8 +39,8 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOD_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK } diff --git a/ports/stm/peripherals/stm32h7/stm32h743xx/gpio.c b/ports/stm/peripherals/stm32h7/stm32h743xx/gpio.c index f89af2714eb57..8b5fa5f3e1c64 100644 --- a/ports/stm/peripherals/stm32h7/stm32h743xx/gpio.c +++ b/ports/stm/peripherals/stm32h7/stm32h743xx/gpio.c @@ -39,8 +39,8 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOD_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK } diff --git a/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c b/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c index e8b805dceccc6..a3f23ad0091cc 100644 --- a/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c +++ b/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c @@ -42,10 +42,10 @@ void stm32_peripherals_gpio_init(void) { // __HAL_RCC_GPIOI_CLK_ENABLE(); // Never reset pins - never_reset_pin_number(2,14); // PC14 OSC32_IN - never_reset_pin_number(2,15); // PC15 OSC32_OUT - never_reset_pin_number(0,13); // PA13 SWDIO - never_reset_pin_number(0,14); // PA14 SWCLK + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK // never_reset_pin_number(0,15); //PA15 JTDI // never_reset_pin_number(1,3); //PB3 JTDO // never_reset_pin_number(1,4); //PB4 JTRST diff --git a/ports/stm/peripherals/stm32l4/stm32l4r5xx/pins.c b/ports/stm/peripherals/stm32l4/stm32l4r5xx/pins.c index e6ef178c52c11..82fdb45554baf 100644 --- a/ports/stm/peripherals/stm32l4/stm32l4r5xx/pins.c +++ b/ports/stm/peripherals/stm32l4/stm32l4r5xx/pins.c @@ -30,14 +30,14 @@ #include STM32_HAL_H -const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1,5)); -const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1,6)); -const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1,7)); -const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1,8)); -const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1,9)); -const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1,10)); -const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1,11)); -const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1,12)); +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 5)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 6)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1, 7)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1, 8)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1, 9)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1, 10)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1, 11)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1, 12)); const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); @@ -46,8 +46,8 @@ const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); -const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1,15)); -const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1,16)); +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1, 15)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1, 16)); const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); @@ -62,12 +62,12 @@ const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); -const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1,1)); -const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1,2)); -const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1,3)); -const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1,4)); -const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1,13)); -const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1,14)); +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_1, 1)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_1, 2)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, ADC_INPUT(ADC_1, 3)); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, ADC_INPUT(ADC_1, 4)); +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_1, 13)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, ADC_INPUT(ADC_1, 14)); const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); diff --git a/ports/stm/supervisor/serial.c b/ports/stm/supervisor/serial.c index 013381e4e3b84..10196fbc31185 100644 --- a/ports/stm/supervisor/serial.c +++ b/ports/stm/supervisor/serial.c @@ -47,7 +47,7 @@ void port_serial_init(void) { huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) == HAL_OK) { - stm32f4_peripherals_status_led(1,1); + stm32f4_peripherals_status_led(1, 1); } #endif } @@ -59,7 +59,7 @@ bool port_serial_connected(void) { char port_serial_read(void) { #if CPY_STM32F4 uint8_t data; - HAL_UART_Receive(&huart2, &data, 1,500); + HAL_UART_Receive(&huart2, &data, 1, 500); return data; #else return -1; diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 5141beff4c15f..a17e46b25e05e 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -28,8 +28,9 @@ UNAME_S := $(shell uname -s) # include py core make definitions include $(TOP)/py/py.mk +include $(TOP)/extmod/extmod.mk -GIT_SUBMODULES = lib/axtls lib/berkeley-db-1.xx lib/libffi +GIT_SUBMODULES += lib/axtls lib/berkeley-db-1.xx lib/libffi INC += -I. INC += -I$(TOP) @@ -224,8 +225,6 @@ SRC_C += \ unix_mphal.c \ mpthreadport.c \ input.c \ - modos.c \ - moduos_vfs.c \ modtime.c \ moduselect.c \ alloc.c \ @@ -264,7 +263,6 @@ ifneq ($(FROZEN_MANIFEST),) # freeze, then invoke make with FROZEN_MANIFEST=manifest.py (be sure to build from scratch). CFLAGS += -DMICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool CFLAGS += -DMICROPY_MODULE_FROZEN_MPY -CFLAGS += -DMICROPY_MODULE_FROZEN_STR CFLAGS += -DMPZ_DIG_SIZE=16 # force 16 bits to work on both 32 and 64 bit archs CFLAGS += -DMICROPY_MODULE_FROZEN_STR endif @@ -368,4 +366,4 @@ install: $(PROG) uninstall: -rm $(BINDIR)/$(PROG) -$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compression.generated.h +$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compressed_translations.generated.h diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index b04bc2158ce61..d2f730a602661 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -2,6 +2,7 @@ #include #include "py/obj.h" +#include "py/objfun.h" #include "py/objstr.h" #include "py/runtime.h" #include "py/gc.h" @@ -220,13 +221,62 @@ STATIC mp_obj_t extra_coverage(void) { gc_unlock(); // using gc_realloc to resize to 0, which means free the memory - void *p = gc_alloc(4, false, false); + void *p = gc_alloc(4, false); mp_printf(&mp_plat_print, "%p\n", gc_realloc(p, 0, false)); // calling gc_nbytes with a non-heap pointer mp_printf(&mp_plat_print, "%p\n", gc_nbytes(NULL)); } + // tracked allocation + { + #define NUM_PTRS (8) + #define NUM_BYTES (128) + #define FLIP_POINTER(p) ((uint8_t *)((uintptr_t)(p) ^ 0x0f)) + + mp_printf(&mp_plat_print, "# tracked allocation\n"); + mp_printf(&mp_plat_print, "m_tracked_head = %p\n", MP_STATE_VM(m_tracked_head)); + + uint8_t *ptrs[NUM_PTRS]; + + // allocate memory blocks + for (size_t i = 0; i < NUM_PTRS; ++i) { + ptrs[i] = m_tracked_calloc(1, NUM_BYTES); + bool all_zero = true; + for (size_t j = 0; j < NUM_BYTES; ++j) { + if (ptrs[i][j] != 0) { + all_zero = false; + break; + } + ptrs[i][j] = j; + } + mp_printf(&mp_plat_print, "%d %d\n", i, all_zero); + + // hide the pointer from the GC and collect + ptrs[i] = FLIP_POINTER(ptrs[i]); + gc_collect(); + } + + // check the memory blocks have the correct content + for (size_t i = 0; i < NUM_PTRS; ++i) { + bool correct_contents = true; + for (size_t j = 0; j < NUM_BYTES; ++j) { + if (FLIP_POINTER(ptrs[i])[j] != j) { + correct_contents = false; + break; + } + } + mp_printf(&mp_plat_print, "%d %d\n", i, correct_contents); + } + + // free the memory blocks + for (size_t i = 0; i < NUM_PTRS; ++i) { + m_tracked_free(FLIP_POINTER(ptrs[i])); + } + + mp_printf(&mp_plat_print, "m_tracked_head = %p\n", MP_STATE_VM(m_tracked_head)); + } + // vstr { mp_printf(&mp_plat_print, "# vstr\n"); @@ -457,7 +507,10 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "# VM\n"); // call mp_execute_bytecode with invalid bytecode (should raise NotImplementedError) + mp_module_context_t context; mp_obj_fun_bc_t fun_bc; + fun_bc.context = &context; + fun_bc.child_table = NULL; fun_bc.bytecode = (const byte *)"\x01"; // just needed for n_state mp_code_state_t *code_state = m_new_obj_var(mp_code_state_t, mp_obj_t, 1); code_state->fun_bc = &fun_bc; @@ -642,14 +695,12 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "# end coverage.c\n"); - mp_obj_streamtest_t *s = m_new_obj(mp_obj_streamtest_t); - s->base.type = &mp_type_stest_fileio; + mp_obj_streamtest_t *s = mp_obj_malloc(mp_obj_streamtest_t, &mp_type_stest_fileio); s->buf = NULL; s->len = 0; s->pos = 0; s->error_code = 0; - mp_obj_streamtest_t *s2 = m_new_obj(mp_obj_streamtest_t); - s2->base.type = &mp_type_stest_textio2; + mp_obj_streamtest_t *s2 = mp_obj_malloc(mp_obj_streamtest_t, &mp_type_stest_textio2); // return a tuple of data for testing on the Python side mp_obj_t items[] = {(mp_obj_t)&str_no_hash_obj, (mp_obj_t)&bytes_no_hash_obj, MP_OBJ_FROM_PTR(s), MP_OBJ_FROM_PTR(s2)}; diff --git a/ports/unix/displayio_min.c b/ports/unix/displayio_min.c index debca1e088151..45cfc1b73cfb1 100644 --- a/ports/unix/displayio_min.c +++ b/ports/unix/displayio_min.c @@ -89,4 +89,4 @@ const mp_obj_module_t displayio_module = { .globals = (mp_obj_dict_t *)&displayio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module, CIRCUITPY_DISPLAYIO_UNIX); +MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module); diff --git a/ports/unix/gccollect.c b/ports/unix/gccollect.c index d9ac53d7f8341..79b17663c32e4 100644 --- a/ports/unix/gccollect.c +++ b/ports/unix/gccollect.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/unix/input.c b/ports/unix/input.c index d66487a7afd7d..c5bf7197388cc 100644 --- a/ports/unix/input.c +++ b/ports/unix/input.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/unix/main.c b/ports/unix/main.c index dcc1c68fe6068..e2ea429439d11 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,7 +39,6 @@ #include #include "py/compile.h" -#include "py/frozenmod.h" #include "py/runtime.h" #include "py/builtin.h" #include "py/repl.h" @@ -47,6 +46,8 @@ #include "py/stackctrl.h" #include "py/mphal.h" #include "py/mpthread.h" +#include "extmod/misc.h" +#include "extmod/moduplatform.h" #include "extmod/vfs.h" #include "extmod/vfs_posix.h" #include "genhdr/mpversion.h" @@ -66,6 +67,9 @@ STATIC void stderr_print_strn(void *env, const char *str, size_t len) { (void)env; ssize_t ret; MP_HAL_RETRY_SYSCALL(ret, write(STDERR_FILENO, str, len), {}); + #if MICROPY_PY_OS_DUPTERM + mp_uos_dupterm_tx_strn(str, len); + #endif } const mp_print_t mp_stderr_print = {NULL, stderr_print_strn}; @@ -176,8 +180,9 @@ STATIC char *strjoin(const char *s1, int sep_char, const char *s2) { #endif STATIC int do_repl(void) { - mp_hal_stdout_tx_str("MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " - MICROPY_PY_SYS_PLATFORM " version\nUse Ctrl-D to exit, Ctrl-E for paste mode\n"); + mp_hal_stdout_tx_str(MICROPY_BANNER_NAME_AND_VERSION); + mp_hal_stdout_tx_str("; " MICROPY_BANNER_MACHINE); + mp_hal_stdout_tx_str("\nUse Ctrl-D to exit, Ctrl-E for paste mode\n"); #if MICROPY_USE_READLINE == 1 @@ -190,7 +195,7 @@ STATIC int do_repl(void) { input_restart: vstr_reset(&line); - int ret = readline(&line, ">>> "); + int ret = readline(&line, mp_repl_get_ps1()); mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT; if (ret == CHAR_CTRL_C) { @@ -237,7 +242,7 @@ STATIC int do_repl(void) { // got a line with non-zero length, see if it needs continuing while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) { vstr_add_byte(&line, '\n'); - ret = readline(&line, "... "); + ret = readline(&line, mp_repl_get_ps2()); if (ret == CHAR_CTRL_C) { // cancel everything printf("\n"); @@ -262,13 +267,13 @@ STATIC int do_repl(void) { // use simple readline for (;;) { - char *line = prompt(">>> "); + char *line = prompt((char *)mp_repl_get_ps1()); if (line == NULL) { // EOF return 0; } while (mp_repl_continue_with_input(line)) { - char *line2 = prompt("... "); + char *line2 = prompt((char *)mp_repl_get_ps2()); if (line2 == NULL) { break; } @@ -325,6 +330,10 @@ STATIC void print_help(char **argv) { , heap_size); impl_opts_cnt++; #endif + #if defined(__APPLE__) + printf(" realtime -- set thread priority to realtime\n"); + impl_opts_cnt++; + #endif if (impl_opts_cnt == 0) { printf(" (none)\n"); @@ -396,6 +405,15 @@ STATIC void pre_process_options(int argc, char **argv) { goto invalid_arg; } #endif + #if defined(__APPLE__) + } else if (strcmp(argv[a + 1], "realtime") == 0) { + #if MICROPY_PY_THREAD + mp_thread_is_realtime_enabled = true; + #endif + // main thread was already initialized before the option + // was parsed, so we have to enable realtime here. + mp_thread_set_realtime(); + #endif } else { invalid_arg: exit(invalid_args()); @@ -695,6 +713,11 @@ MP_NOINLINE int main_(int argc, char **argv) { } #endif + #if MICROPY_PY_BLUETOOTH + void mp_bluetooth_deinit(void); + mp_bluetooth_deinit(); + #endif + #if MICROPY_PY_THREAD mp_thread_deinit(); #endif @@ -715,38 +738,6 @@ MP_NOINLINE int main_(int argc, char **argv) { return ret & 0xff; } -#if !MICROPY_VFS -mp_import_stat_t mp_import_stat(const char *path) { - struct stat st; - if (stat(path, &st) == 0) { - if (S_ISDIR(st.st_mode)) { - return MP_IMPORT_STAT_DIR; - } else if (S_ISREG(st.st_mode)) { - return MP_IMPORT_STAT_FILE; - } - } - return MP_IMPORT_STAT_NO_EXIST; -} - -#if MICROPY_PY_IO -// Factory function for I/O stream classes, only needed if generic VFS subsystem isn't used. -// Note: buffering and encoding are currently ignored. -mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kwargs) { - enum { ARG_file, ARG_mode }; - STATIC const mp_arg_t allowed_args[] = { - { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_mode, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_r)} }, - { MP_QSTR_buffering, MP_ARG_INT, {.u_int = -1} }, - { MP_QSTR_encoding, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, kwargs, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - return mp_vfs_posix_file_open(&mp_type_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj); -} -MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open); -#endif -#endif - void nlr_jump_fail(void *val) { fprintf(stderr, "FATAL: uncaught NLR %p\n", val); exit(1); diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index d8b63b571e855..468006ba5d7ef 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -228,8 +228,7 @@ STATIC mp_obj_t make_func(mp_obj_t rettype_in, void *func, mp_obj_t argtypes_in) const char *argtypes = mp_obj_str_get_str(argtypes_in); mp_int_t nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(argtypes_in)); - mp_obj_ffifunc_t *o = m_new_obj_var(mp_obj_ffifunc_t, ffi_type *, nparams); - o->base.type = &ffifunc_type; + mp_obj_ffifunc_t *o = mp_obj_malloc_var(mp_obj_ffifunc_t, ffi_type *, nparams, &ffifunc_type); o->func = func; o->rettype = *rettype; @@ -245,7 +244,7 @@ STATIC mp_obj_t make_func(mp_obj_t rettype_in, void *func, mp_obj_t argtypes_in) int res = ffi_prep_cif(&o->cif, FFI_DEFAULT_ABI, nparams, char2ffi_type(*rettype), o->params); if (res != FFI_OK) { - mp_raise_ValueError(MP_ERROR_TEXT("Error in ffi_prep_cif")); + mp_raise_ValueError(MP_ERROR_TEXT("error in ffi_prep_cif")); } return MP_OBJ_FROM_PTR(o); @@ -336,8 +335,7 @@ STATIC mp_obj_t mod_ffi_callback(size_t n_args, const mp_obj_t *pos_args, mp_map const char *rettype = mp_obj_str_get_str(rettype_in); mp_int_t nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(paramtypes_in)); - mp_obj_fficallback_t *o = m_new_obj_var(mp_obj_fficallback_t, ffi_type *, nparams); - o->base.type = &fficallback_type; + mp_obj_fficallback_t *o = mp_obj_malloc_var(mp_obj_fficallback_t, ffi_type *, nparams, &fficallback_type); o->clo = ffi_closure_alloc(sizeof(ffi_closure), &o->func); @@ -376,8 +374,7 @@ STATIC mp_obj_t ffimod_var(mp_obj_t self_in, mp_obj_t vartype_in, mp_obj_t symna if (sym == NULL) { mp_raise_OSError(MP_ENOENT); } - mp_obj_ffivar_t *o = m_new_obj(mp_obj_ffivar_t); - o->base.type = &ffivar_type; + mp_obj_ffivar_t *o = mp_obj_malloc(mp_obj_ffivar_t, &ffivar_type); o->var = sym; o->type = *rettype; @@ -410,8 +407,7 @@ STATIC mp_obj_t ffimod_make_new(const mp_obj_type_t *type, size_t n_args, size_t if (mod == NULL) { mp_raise_OSError(errno); } - mp_obj_ffimod_t *o = m_new_obj(mp_obj_ffimod_t); - o->base.type = type; + mp_obj_ffimod_t *o = mp_obj_malloc(mp_obj_ffimod_t, type); o->handle = mod; return MP_OBJ_FROM_PTR(o); } diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index bd151050eae49..c86f30653c81a 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -35,6 +35,8 @@ #include +#if MICROPY_PY_JNI + #define JJ(call, ...) (*env)->call(env, __VA_ARGS__) #define JJ1(call) (*env)->call(env) #define MATCH(s, static) (!strncmp(s, static, sizeof(static) - 1)) @@ -145,8 +147,7 @@ STATIC void jclass_attr(mp_obj_t self_in, qstr attr_in, mp_obj_t *dest) { // JJ1(ExceptionDescribe); JJ1(ExceptionClear); - mp_obj_jmethod_t *o = m_new_obj(mp_obj_jmethod_t); - o->base.type = &jmethod_type; + mp_obj_jmethod_t *o = mp_obj_malloc(mp_obj_jmethod_t, &jmethod_type); o->name = attr_in; o->meth = NULL; o->obj = self->cls; @@ -183,8 +184,7 @@ STATIC const mp_obj_type_t jclass_type = { }; STATIC mp_obj_t new_jclass(jclass jc) { - mp_obj_jclass_t *o = m_new_obj(mp_obj_jclass_t); - o->base.type = &jclass_type; + mp_obj_jclass_t *o = mp_obj_malloc(mp_obj_jclass_t, &jclass_type); o->cls = jc; return MP_OBJ_FROM_PTR(o); } @@ -223,8 +223,7 @@ STATIC void jobject_attr(mp_obj_t self_in, qstr attr_in, mp_obj_t *dest) { // JJ1(ExceptionDescribe); JJ1(ExceptionClear); - mp_obj_jmethod_t *o = m_new_obj(mp_obj_jmethod_t); - o->base.type = &jmethod_type; + mp_obj_jmethod_t *o = mp_obj_malloc(mp_obj_jmethod_t, &jmethod_type); o->name = attr_in; o->meth = NULL; o->obj = self->obj; @@ -343,8 +342,7 @@ STATIC mp_obj_t new_jobject(jobject jo) { } else if (JJ(IsInstanceOf, jo, Class_class)) { return new_jclass(jo); } else { - mp_obj_jobject_t *o = m_new_obj(mp_obj_jobject_t); - o->base.type = &jobject_type; + mp_obj_jobject_t *o = mp_obj_malloc(mp_obj_jobject_t, &jobject_type); o->obj = jo; return MP_OBJ_FROM_PTR(o); } @@ -644,8 +642,7 @@ STATIC mp_obj_t mod_jni_cls(mp_obj_t cls_name_in) { } jclass cls = JJ(FindClass, cls_name); - mp_obj_jclass_t *o = m_new_obj(mp_obj_jclass_t); - o->base.type = &jclass_type; + mp_obj_jclass_t *o = mp_obj_malloc(mp_obj_jclass_t, &jclass_type); o->cls = cls; return MP_OBJ_FROM_PTR(o); } @@ -717,3 +714,7 @@ const mp_obj_module_t mp_module_jni = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&mp_module_jni_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_jni, mp_module_jni); + +#endif // MICROPY_PY_JNI diff --git a/ports/unix/modmachine.c b/ports/unix/modmachine.c index 987c70b26e001..bcbf39406f7a1 100644 --- a/ports/unix/modmachine.c +++ b/ports/unix/modmachine.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2015 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2015 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -112,4 +112,6 @@ const mp_obj_module_t mp_module_machine = { .globals = (mp_obj_dict_t *)&machine_module_globals, }; +MP_REGISTER_MODULE(MP_QSTR_umachine, mp_module_machine); + #endif // MICROPY_PY_MACHINE diff --git a/ports/unix/modos.c b/ports/unix/modos.c deleted file mode 100644 index 8373c07a5c89d..0000000000000 --- a/ports/unix/modos.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky - * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _MSC_VER -#include // For mkdir -#endif -#include "py/mpconfig.h" - -#include "py/runtime.h" -#include "py/objtuple.h" -#include "py/mphal.h" -#include "py/mpthread.h" -#include "extmod/vfs.h" - -#ifdef __ANDROID__ -#define USE_STATFS 1 -#endif - -#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) -#if __GLIBC_PREREQ(2, 25) -#include -#define _HAVE_GETRANDOM -#endif -#endif - -#if defined(MICROPY_UNIX_COVERAGE) -#include "py/objstr.h" -typedef int os_getenv_err_t; -mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_); -os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len); -os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); -#endif - -STATIC mp_obj_t mod_os_urandom(mp_obj_t num) { - mp_int_t n = mp_obj_get_int(num); - vstr_t vstr; - vstr_init_len(&vstr, n); - #ifdef _HAVE_GETRANDOM - RAISE_ERRNO(getrandom(vstr.buf, n, 0), errno); - #else - int fd = open("/dev/urandom", O_RDONLY); - RAISE_ERRNO(fd, errno); - RAISE_ERRNO(read(fd, vstr.buf, n), errno); - close(fd); - #endif - return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_urandom_obj, mod_os_urandom); - -STATIC mp_obj_t mod_os_stat(mp_obj_t path_in) { - struct stat sb; - const char *path = mp_obj_str_get_str(path_in); - - int res; - MP_HAL_RETRY_SYSCALL(res, stat(path, &sb), mp_raise_OSError(err)); - - mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); - t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.st_mode); - t->items[1] = mp_obj_new_int_from_uint(sb.st_ino); - t->items[2] = mp_obj_new_int_from_uint(sb.st_dev); - t->items[3] = mp_obj_new_int_from_uint(sb.st_nlink); - t->items[4] = mp_obj_new_int_from_uint(sb.st_uid); - t->items[5] = mp_obj_new_int_from_uint(sb.st_gid); - t->items[6] = mp_obj_new_int_from_uint(sb.st_size); - t->items[7] = mp_obj_new_int_from_uint(sb.st_atime); - t->items[8] = mp_obj_new_int_from_uint(sb.st_mtime); - t->items[9] = mp_obj_new_int_from_uint(sb.st_ctime); - return MP_OBJ_FROM_PTR(t); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_stat_obj, mod_os_stat); - -#if MICROPY_PY_OS_STATVFS - -#if USE_STATFS -#include -#define STRUCT_STATVFS struct statfs -#define STATVFS statfs -#define F_FAVAIL sb.f_ffree -#define F_NAMEMAX sb.f_namelen -#define F_FLAG sb.f_flags -#else -#include -#define STRUCT_STATVFS struct statvfs -#define STATVFS statvfs -#define F_FAVAIL sb.f_favail -#define F_NAMEMAX sb.f_namemax -#define F_FLAG sb.f_flag -#endif - -STATIC mp_obj_t mod_os_statvfs(mp_obj_t path_in) { - STRUCT_STATVFS sb; - const char *path = mp_obj_str_get_str(path_in); - - int res; - MP_HAL_RETRY_SYSCALL(res, STATVFS(path, &sb), mp_raise_OSError(err)); - - mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); - t->items[0] = MP_OBJ_NEW_SMALL_INT(sb.f_bsize); - t->items[1] = MP_OBJ_NEW_SMALL_INT(sb.f_frsize); - t->items[2] = MP_OBJ_NEW_SMALL_INT(sb.f_blocks); - t->items[3] = MP_OBJ_NEW_SMALL_INT(sb.f_bfree); - t->items[4] = MP_OBJ_NEW_SMALL_INT(sb.f_bavail); - t->items[5] = MP_OBJ_NEW_SMALL_INT(sb.f_files); - t->items[6] = MP_OBJ_NEW_SMALL_INT(sb.f_ffree); - t->items[7] = MP_OBJ_NEW_SMALL_INT(F_FAVAIL); - t->items[8] = MP_OBJ_NEW_SMALL_INT(F_FLAG); - t->items[9] = MP_OBJ_NEW_SMALL_INT(F_NAMEMAX); - return MP_OBJ_FROM_PTR(t); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_statvfs_obj, mod_os_statvfs); -#endif - -STATIC mp_obj_t mod_os_remove(mp_obj_t path_in) { - const char *path = mp_obj_str_get_str(path_in); - - // Note that POSIX requires remove() to be able to delete a directory - // too (act as rmdir()). This is POSIX extension to ANSI C semantics - // of that function. But Python remove() follows ANSI C, and explicitly - // required to raise exception on attempt to remove a directory. Thus, - // call POSIX unlink() here. - MP_THREAD_GIL_EXIT(); - int r = unlink(path); - MP_THREAD_GIL_ENTER(); - - RAISE_ERRNO(r, errno); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_remove_obj, mod_os_remove); - -STATIC mp_obj_t mod_os_rename(mp_obj_t old_path_in, mp_obj_t new_path_in) { - const char *old_path = mp_obj_str_get_str(old_path_in); - const char *new_path = mp_obj_str_get_str(new_path_in); - - MP_THREAD_GIL_EXIT(); - int r = rename(old_path, new_path); - MP_THREAD_GIL_ENTER(); - - RAISE_ERRNO(r, errno); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_os_rename_obj, mod_os_rename); - -STATIC mp_obj_t mod_os_rmdir(mp_obj_t path_in) { - const char *path = mp_obj_str_get_str(path_in); - - MP_THREAD_GIL_EXIT(); - int r = rmdir(path); - MP_THREAD_GIL_ENTER(); - - RAISE_ERRNO(r, errno); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_rmdir_obj, mod_os_rmdir); - -STATIC mp_obj_t mod_os_system(mp_obj_t cmd_in) { - const char *cmd = mp_obj_str_get_str(cmd_in); - - MP_THREAD_GIL_EXIT(); - int r = system(cmd); - MP_THREAD_GIL_ENTER(); - - RAISE_ERRNO(r, errno); - - return MP_OBJ_NEW_SMALL_INT(r); -} -MP_DEFINE_CONST_FUN_OBJ_1(mod_os_system_obj, mod_os_system); - -STATIC mp_obj_t mod_os_getenv(mp_obj_t var_in) { - #if defined(MICROPY_UNIX_COVERAGE) - mp_obj_t result = common_hal_os_getenv(mp_obj_str_get_str(var_in), mp_const_none); - if (result != mp_const_none) { - return result; - } - #endif - const char *s = getenv(mp_obj_str_get_str(var_in)); - if (s == NULL) { - return mp_const_none; - } - return mp_obj_new_str(s, strlen(s)); -} -MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_obj, mod_os_getenv); - -#if defined(MICROPY_UNIX_COVERAGE) -STATIC mp_obj_t mod_os_getenv_int(mp_obj_t var_in) { - mp_int_t value; - os_getenv_err_t result = common_hal_os_getenv_int(mp_obj_str_get_str(var_in), &value); - if (result == 0) { - return mp_obj_new_int(value); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_int_obj, mod_os_getenv_int); - -STATIC mp_obj_t mod_os_getenv_str(mp_obj_t var_in) { - char buf[4096]; - os_getenv_err_t result = common_hal_os_getenv_str(mp_obj_str_get_str(var_in), buf, sizeof(buf)); - if (result == 0) { - return mp_obj_new_str_copy(&mp_type_str, (byte *)buf, strlen(buf)); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_str_obj, mod_os_getenv_str); -#endif - -STATIC mp_obj_t mod_os_putenv(mp_obj_t key_in, mp_obj_t value_in) { - const char *key = mp_obj_str_get_str(key_in); - const char *value = mp_obj_str_get_str(value_in); - int ret; - - #if _WIN32 - ret = _putenv_s(key, value); - #else - ret = setenv(key, value, 1); - #endif - - if (ret == -1) { - mp_raise_OSError(errno); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(mod_os_putenv_obj, mod_os_putenv); - -STATIC mp_obj_t mod_os_unsetenv(mp_obj_t key_in) { - const char *key = mp_obj_str_get_str(key_in); - int ret; - - #if _WIN32 - ret = _putenv_s(key, ""); - #else - ret = unsetenv(key); - #endif - - if (ret == -1) { - mp_raise_OSError(errno); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(mod_os_unsetenv_obj, mod_os_unsetenv); - -STATIC mp_obj_t mod_os_mkdir(mp_obj_t path_in) { - // TODO: Accept mode param - const char *path = mp_obj_str_get_str(path_in); - MP_THREAD_GIL_EXIT(); - #ifdef _WIN32 - int r = mkdir(path); - #else - int r = mkdir(path, 0777); - #endif - MP_THREAD_GIL_ENTER(); - RAISE_ERRNO(r, errno); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_os_mkdir_obj, mod_os_mkdir); - -typedef struct _mp_obj_listdir_t { - mp_obj_base_t base; - mp_fun_1_t iternext; - DIR *dir; -} mp_obj_listdir_t; - -STATIC mp_obj_t listdir_next(mp_obj_t self_in) { - mp_obj_listdir_t *self = MP_OBJ_TO_PTR(self_in); - - if (self->dir == NULL) { - goto done; - } - MP_THREAD_GIL_EXIT(); - struct dirent *dirent = readdir(self->dir); - if (dirent == NULL) { - closedir(self->dir); - MP_THREAD_GIL_ENTER(); - self->dir = NULL; - done: - return MP_OBJ_STOP_ITERATION; - } - MP_THREAD_GIL_ENTER(); - - mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); - t->items[0] = mp_obj_new_str(dirent->d_name, strlen(dirent->d_name)); - - #ifdef _DIRENT_HAVE_D_TYPE - #ifdef DTTOIF - t->items[1] = MP_OBJ_NEW_SMALL_INT(DTTOIF(dirent->d_type)); - #else - if (dirent->d_type == DT_DIR) { - t->items[1] = MP_OBJ_NEW_SMALL_INT(MP_S_IFDIR); - } else if (dirent->d_type == DT_REG) { - t->items[1] = MP_OBJ_NEW_SMALL_INT(MP_S_IFREG); - } else { - t->items[1] = MP_OBJ_NEW_SMALL_INT(dirent->d_type); - } - #endif - #else - // DT_UNKNOWN should have 0 value on any reasonable system - t->items[1] = MP_OBJ_NEW_SMALL_INT(0); - #endif - - #ifdef _DIRENT_HAVE_D_INO - t->items[2] = MP_OBJ_NEW_SMALL_INT(dirent->d_ino); - #else - t->items[2] = MP_OBJ_NEW_SMALL_INT(0); - #endif - return MP_OBJ_FROM_PTR(t); -} - -STATIC mp_obj_t mod_os_ilistdir(size_t n_args, const mp_obj_t *args) { - const char *path = "."; - if (n_args > 0) { - path = mp_obj_str_get_str(args[0]); - } - mp_obj_listdir_t *o = m_new_obj(mp_obj_listdir_t); - o->base.type = &mp_type_polymorph_iter; - MP_THREAD_GIL_EXIT(); - o->dir = opendir(path); - MP_THREAD_GIL_ENTER(); - o->iternext = listdir_next; - return MP_OBJ_FROM_PTR(o); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_ilistdir_obj, 0, 1, mod_os_ilistdir); - -STATIC mp_obj_t mod_os_errno(size_t n_args, const mp_obj_t *args) { - if (n_args == 0) { - return MP_OBJ_NEW_SMALL_INT(errno); - } - - errno = mp_obj_get_int(args[0]); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_errno_obj, 0, 1, mod_os_errno); - -STATIC const mp_rom_map_elem_t mp_module_os_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos) }, - { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mod_os_errno_obj) }, - { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mod_os_stat_obj) }, - { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mod_os_urandom_obj) }, - #if MICROPY_PY_OS_STATVFS - { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mod_os_statvfs_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mod_os_system_obj) }, - { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mod_os_remove_obj) }, - { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mod_os_rename_obj) }, - { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mod_os_rmdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mod_os_getenv_obj) }, - #if defined(MICROPY_UNIX_COVERAGE) - { MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mod_os_getenv_int_obj) }, - { MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mod_os_getenv_str_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mod_os_putenv_obj) }, - { MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mod_os_unsetenv_obj) }, - { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mod_os_mkdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mod_os_ilistdir_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(mp_module_os_globals, mp_module_os_globals_table); - -const mp_obj_module_t mp_module_os = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&mp_module_os_globals, -}; diff --git a/ports/unix/modtermios.c b/ports/unix/modtermios.c index 4adef8a380bf2..4f9751e274378 100644 --- a/ports/unix/modtermios.c +++ b/ports/unix/modtermios.c @@ -33,6 +33,8 @@ #include "py/runtime.h" #include "py/mphal.h" +#if MICROPY_PY_TERMIOS + STATIC mp_obj_t mod_termios_tcgetattr(mp_obj_t fd_in) { struct termios term; int fd = mp_obj_get_int(fd_in); @@ -148,3 +150,7 @@ const mp_obj_module_t mp_module_termios = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&mp_module_termios_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_termios, mp_module_termios); + +#endif // MICROPY_PY_TERMIOS diff --git a/ports/unix/modtime.c b/ports/unix/modtime.c index e72c611d1b122..c9eb09c15bdd8 100644 --- a/ports/unix/modtime.c +++ b/ports/unix/modtime.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Damien P. George + * Copyright (c) 2014-2017 Paul Sokolovsky + * Copyright (c) 2014-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,7 +45,7 @@ static inline int msec_sleep_tv(struct timeval *tv) { msec_sleep(tv->tv_sec * 1000.0 + tv->tv_usec / 1000.0); return 0; } -#define sleep_select(a,b,c,d,e) msec_sleep_tv((e)) +#define sleep_select(a, b, c, d, e) msec_sleep_tv((e)) #else #define sleep_select select #endif @@ -232,4 +232,6 @@ const mp_obj_module_t mp_module_time = { .globals = (mp_obj_dict_t *)&mp_module_time_globals, }; +MP_REGISTER_MODULE(MP_QSTR_utime, mp_module_time); + #endif // MICROPY_PY_UTIME diff --git a/ports/unix/moduos.c b/ports/unix/moduos.c new file mode 100644 index 0000000000000..e352b9f27b602 --- /dev/null +++ b/ports/unix/moduos.c @@ -0,0 +1,144 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2018 Paul Sokolovsky + * Copyright (c) 2017-2022 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/runtime.h" +#include "py/mphal.h" + +#if defined(MICROPY_UNIX_COVERAGE) +#include "py/objstr.h" +typedef int os_getenv_err_t; +mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_); +os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len); +os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); +#endif + +STATIC mp_obj_t mp_uos_getenv(mp_obj_t var_in) { + #if defined(MICROPY_UNIX_COVERAGE) + mp_obj_t result = common_hal_os_getenv(mp_obj_str_get_str(var_in), mp_const_none); + if (result != mp_const_none) { + return result; + } + #endif + const char *s = getenv(mp_obj_str_get_str(var_in)); + if (s == NULL) { + return mp_const_none; + } + return mp_obj_new_str(s, strlen(s)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_getenv_obj, mp_uos_getenv); + +#if defined(MICROPY_UNIX_COVERAGE) +STATIC mp_obj_t mp_uos_getenv_int(mp_obj_t var_in) { + mp_int_t value; + os_getenv_err_t result = common_hal_os_getenv_int(mp_obj_str_get_str(var_in), &value); + if (result == 0) { + return mp_obj_new_int(value); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_getenv_int_obj, mp_uos_getenv_int); + +STATIC mp_obj_t mp_uos_getenv_str(mp_obj_t var_in) { + char buf[4096]; + os_getenv_err_t result = common_hal_os_getenv_str(mp_obj_str_get_str(var_in), buf, sizeof(buf)); + if (result == 0) { + return mp_obj_new_str_copy(&mp_type_str, (byte *)buf, strlen(buf)); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_getenv_str_obj, mp_uos_getenv_str); +#endif + +STATIC mp_obj_t mp_uos_putenv(mp_obj_t key_in, mp_obj_t value_in) { + const char *key = mp_obj_str_get_str(key_in); + const char *value = mp_obj_str_get_str(value_in); + int ret; + + #if _WIN32 + ret = _putenv_s(key, value); + #else + ret = setenv(key, value, 1); + #endif + + if (ret == -1) { + mp_raise_OSError(errno); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(mp_uos_putenv_obj, mp_uos_putenv); + +STATIC mp_obj_t mp_uos_unsetenv(mp_obj_t key_in) { + const char *key = mp_obj_str_get_str(key_in); + int ret; + + #if _WIN32 + ret = _putenv_s(key, ""); + #else + ret = unsetenv(key); + #endif + + if (ret == -1) { + mp_raise_OSError(errno); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_unsetenv_obj, mp_uos_unsetenv); + +STATIC mp_obj_t mp_uos_system(mp_obj_t cmd_in) { + const char *cmd = mp_obj_str_get_str(cmd_in); + + MP_THREAD_GIL_EXIT(); + int r = system(cmd); + MP_THREAD_GIL_ENTER(); + + RAISE_ERRNO(r, errno); + + return MP_OBJ_NEW_SMALL_INT(r); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_system_obj, mp_uos_system); + +STATIC mp_obj_t mp_uos_urandom(mp_obj_t num) { + mp_int_t n = mp_obj_get_int(num); + vstr_t vstr; + vstr_init_len(&vstr, n); + mp_hal_get_random(n, vstr.buf); + return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_uos_urandom_obj, mp_uos_urandom); + +STATIC mp_obj_t mp_uos_errno(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + return MP_OBJ_NEW_SMALL_INT(errno); + } + + errno = mp_obj_get_int(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_errno_obj, 0, 1, mp_uos_errno); diff --git a/ports/unix/moduos_vfs.c b/ports/unix/moduos_vfs.c deleted file mode 100644 index 495679290a772..0000000000000 --- a/ports/unix/moduos_vfs.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "extmod/vfs.h" -#include "extmod/vfs_posix.h" -#include "extmod/vfs_fat.h" -#include "extmod/vfs_lfs.h" - -#if MICROPY_VFS - -// These are defined in modos.c -MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mod_os_errno_obj); -MP_DECLARE_CONST_FUN_OBJ_1(mod_os_getenv_obj); -#if defined(MICROPY_UNIX_COVERAGE) -MP_DECLARE_CONST_FUN_OBJ_1(mod_os_getenv_int_obj); -MP_DECLARE_CONST_FUN_OBJ_1(mod_os_getenv_str_obj); -#endif -MP_DECLARE_CONST_FUN_OBJ_1(mod_os_putenv_obj); -MP_DECLARE_CONST_FUN_OBJ_1(mod_os_unsetenv_obj); -MP_DECLARE_CONST_FUN_OBJ_1(mod_os_system_obj); - -STATIC const mp_rom_map_elem_t uos_vfs_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uos_vfs) }, - { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) }, - - { MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mod_os_errno_obj) }, - { MP_ROM_QSTR(MP_QSTR_getenv), MP_ROM_PTR(&mod_os_getenv_obj) }, - #if defined(MICROPY_UNIX_COVERAGE) - { MP_ROM_QSTR(MP_QSTR_getenv_int), MP_ROM_PTR(&mod_os_getenv_int_obj) }, - { MP_ROM_QSTR(MP_QSTR_getenv_str), MP_ROM_PTR(&mod_os_getenv_str_obj) }, - #endif - { MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mod_os_putenv_obj) }, - { MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mod_os_unsetenv_obj) }, - { MP_ROM_QSTR(MP_QSTR_system), MP_ROM_PTR(&mod_os_system_obj) }, - - { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&mp_vfs_mount_obj) }, - { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_vfs_umount_obj) }, - - { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) }, - { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&mp_vfs_ilistdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) }, - { MP_ROM_QSTR(MP_QSTR_rename),MP_ROM_PTR(&mp_vfs_rename_obj) }, - { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) }, - { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) }, - { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) }, - { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove - - #if MICROPY_VFS_POSIX - { MP_ROM_QSTR(MP_QSTR_VfsPosix), MP_ROM_PTR(&mp_type_vfs_posix) }, - #endif - #if MICROPY_VFS_FAT - { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, - #endif - #if MICROPY_VFS_LFS1 - { MP_ROM_QSTR(MP_QSTR_VfsLfs1), MP_ROM_PTR(&mp_type_vfs_lfs1) }, - #endif - #if MICROPY_VFS_LFS2 - { MP_ROM_QSTR(MP_QSTR_VfsLfs2), MP_ROM_PTR(&mp_type_vfs_lfs2) }, - #endif -}; - -STATIC MP_DEFINE_CONST_DICT(uos_vfs_module_globals, uos_vfs_module_globals_table); - -const mp_obj_module_t mp_module_uos_vfs = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&uos_vfs_module_globals, -}; - -#endif // MICROPY_VFS diff --git a/ports/unix/moduselect.c b/ports/unix/moduselect.c index fe09c33c8503c..7bfcf8fc562b6 100644 --- a/ports/unix/moduselect.c +++ b/ports/unix/moduselect.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * Copyright (c) 2014 Damien P. George * Copyright (c) 2015-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -327,8 +327,7 @@ STATIC mp_obj_t select_poll(size_t n_args, const mp_obj_t *args) { if (n_args > 0) { alloc = mp_obj_get_int(args[0]); } - mp_obj_poll_t *poll = m_new_obj(mp_obj_poll_t); - poll->base.type = &mp_type_poll; + mp_obj_poll_t *poll = mp_obj_malloc(mp_obj_poll_t, &mp_type_poll); poll->entries = m_new(struct pollfd, alloc); poll->alloc = alloc; poll->len = 0; @@ -355,4 +354,6 @@ const mp_obj_module_t mp_module_uselect = { .globals = (mp_obj_dict_t *)&mp_module_select_globals, }; +MP_REGISTER_MODULE(MP_QSTR_uselect, mp_module_uselect); + #endif // MICROPY_PY_USELECT_POSIX diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index 237b99bfe861c..a9e6cf988556d 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,8 +34,81 @@ // If we're building the minimal variant, ignore the rest of this file. #ifndef MICROPY_UNIX_MINIMAL +// CIRCUITPY +#define CIRCUITPY_MICROPYTHON_ADVANCED (1) +#define MICROPY_PY_ASYNC_AWAIT (1) + +// If the variant did not set a feature level then configure a set of features. +#ifndef MICROPY_CONFIG_ROM_LEVEL +#define MICROPY_COMP_MODULE_CONST (1) +#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) +#define MICROPY_COMP_RETURN_IF_EXPR (1) +#ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH +#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) +#endif +#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE +#define MICROPY_OPT_MAP_LOOKUP_CACHE (1) +#endif +#define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_STACK_CHECK (1) +#define MICROPY_KBD_EXCEPTION (1) +#define MICROPY_HELPER_REPL (1) +#define MICROPY_REPL_EMACS_KEYS (1) +#define MICROPY_REPL_AUTO_INDENT (1) +#define MICROPY_ENABLE_SOURCE_LINE (1) +#ifndef MICROPY_STREAMS_NON_BLOCK +#define MICROPY_STREAMS_NON_BLOCK (1) +#endif +#define MICROPY_MODULE_WEAK_LINKS (1) +#define MICROPY_CAN_OVERRIDE_BUILTINS (1) +#define MICROPY_PY_FUNCTION_ATTRS (1) +#define MICROPY_PY_DESCRIPTORS (1) +#define MICROPY_PY_DELATTR_SETATTR (1) +#define MICROPY_PY_FSTRINGS (1) +#define MICROPY_PY_BUILTINS_STR_UNICODE (1) +#define MICROPY_PY_BUILTINS_STR_CENTER (1) +#define MICROPY_PY_BUILTINS_STR_PARTITION (1) +#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) +#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) +#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) +#define MICROPY_PY_BUILTINS_SLICE_INDICES (1) +#define MICROPY_PY_BUILTINS_FROZENSET (1) +#define MICROPY_PY_BUILTINS_ROUND_INT (1) +#define MICROPY_PY_ALL_SPECIAL_METHODS (1) +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) +#define MICROPY_PY_BUILTINS_COMPILE (1) +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) +#define MICROPY_PY_BUILTINS_INPUT (1) +#define MICROPY_PY_BUILTINS_POW3 (1) +#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) +#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) +#define MICROPY_PY_COLLECTIONS_DEQUE (1) +#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1) +#ifndef MICROPY_PY_MATH_SPECIAL_FUNCTIONS +#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) +#endif +#define MICROPY_PY_MATH_ISCLOSE (MICROPY_PY_MATH_SPECIAL_FUNCTIONS) +#define MICROPY_PY_CMATH (1) +#define MICROPY_PY_IO_IOBASE (1) +#define MICROPY_PY_IO_FILEIO (1) +#define MICROPY_PY_SYS_MAXSIZE (1) +#define MICROPY_PY_SYS_STDFILES (1) +#define MICROPY_PY_UERRNO (1) +#define MICROPY_PY_UCTYPES (1) +#define MICROPY_PY_UZLIB (1) +#define MICROPY_PY_UJSON (1) +#define MICROPY_PY_UOS (1) +#define MICROPY_PY_URE (1) +#define MICROPY_PY_UHEAPQ (1) +#define MICROPY_PY_UHASHLIB (1) +#define MICROPY_PY_UBINASCII (1) +#define MICROPY_PY_UBINASCII_CRC32 (1) +#define MICROPY_PY_URANDOM (1) +#endif + #define MICROPY_ALLOC_PATH_MAX (PATH_MAX) #define MICROPY_PERSISTENT_CODE_LOAD (1) + #if !defined(MICROPY_EMIT_X64) && defined(__x86_64__) #define MICROPY_EMIT_X64 (1) #endif @@ -51,69 +124,29 @@ #if !defined(MICROPY_EMIT_ARM) && defined(__arm__) && !defined(__thumb2__) #define MICROPY_EMIT_ARM (1) #endif -#define MICROPY_COMP_MODULE_CONST (1) -#define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) -#define MICROPY_COMP_RETURN_IF_EXPR (1) #define MICROPY_ENABLE_GC (1) -#define MICROPY_ENABLE_FINALISER (1) -#define MICROPY_STACK_CHECK (1) #define MICROPY_MALLOC_USES_ALLOCATED_SIZE (1) #define MICROPY_MEM_STATS (1) #define MICROPY_DEBUG_PRINTERS (1) -#define CIRCUITPY_MICROPYTHON_ADVANCED (1) // Printing debug to stderr may give tests which // check stdout a chance to pass, etc. #define MICROPY_DEBUG_PRINTER (&mp_stderr_print) #define MICROPY_READER_POSIX (1) +#define MICROPY_READER_VFS (1) #define MICROPY_USE_READLINE_HISTORY (1) -#define MICROPY_HELPER_REPL (1) -#define MICROPY_REPL_EMACS_KEYS (1) -#define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_HELPER_LEXER_UNIX (1) -#define MICROPY_ENABLE_SOURCE_LINE (1) #ifndef MICROPY_FLOAT_IMPL #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE) #endif #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) -#ifndef MICROPY_STREAMS_NON_BLOCK -#define MICROPY_STREAMS_NON_BLOCK (1) -#endif #define MICROPY_STREAMS_POSIX_API (1) #define MICROPY_OPT_COMPUTED_GOTO (1) -#ifndef MICROPY_OPT_LOAD_ATTR_FAST_PATH -#define MICROPY_OPT_LOAD_ATTR_FAST_PATH (1) -#endif -#ifndef MICROPY_OPT_MAP_LOOKUP_CACHE -#define MICROPY_OPT_MAP_LOOKUP_CACHE (1) -#endif -#define MICROPY_MODULE_WEAK_LINKS (1) #define MICROPY_MODULE_OVERRIDE_MAIN_IMPORT (1) -#define MICROPY_CAN_OVERRIDE_BUILTINS (1) -#define MICROPY_VFS_POSIX_FILE (1) -#define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_DESCRIPTORS (1) -#define MICROPY_PY_DELATTR_SETATTR (1) -#define MICROPY_PY_FSTRINGS (1) -#define MICROPY_PY_BUILTINS_STR_UNICODE (1) -#define MICROPY_PY_BUILTINS_STR_CENTER (1) -#define MICROPY_PY_BUILTINS_STR_PARTITION (1) -#define MICROPY_PY_BUILTINS_STR_SPLITLINES (1) -#define MICROPY_PY_BUILTINS_MEMORYVIEW (1) -#define MICROPY_PY_BUILTINS_FROZENSET (1) -#define MICROPY_PY_BUILTINS_COMPILE (1) -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) -#define MICROPY_PY_BUILTINS_INPUT (1) -#define MICROPY_PY_BUILTINS_POW3 (1) -#define MICROPY_PY_BUILTINS_ROUND_INT (1) -#define MICROPY_PY_MICROPYTHON_MEM_INFO (1) -#define MICROPY_PY_ALL_SPECIAL_METHODS (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) -#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) -#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1) -#define MICROPY_PY_BUILTINS_SLICE_INDICES (1) -#define MICROPY_PY_SYS_ATEXIT (1) +#define MICROPY_VFS (1) +#define MICROPY_VFS_POSIX (1) #define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0) #define MICROPY_PY_SYS_EXIT (1) +#define MICROPY_PY_SYS_ATEXIT (1) #if MICROPY_PY_SYS_SETTRACE #define MICROPY_PERSISTENT_CODE_SAVE (1) #define MICROPY_COMP_CONST (0) @@ -128,17 +161,7 @@ #ifndef MICROPY_PY_SYS_PATH_DEFAULT #define MICROPY_PY_SYS_PATH_DEFAULT ".frozen:~/.micropython/lib:/usr/lib/micropython" #endif -#define MICROPY_PY_SYS_MAXSIZE (1) -#define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_SYS_EXC_INFO (1) -#define MICROPY_PY_COLLECTIONS_DEQUE (1) -#ifndef MICROPY_PY_MATH_SPECIAL_FUNCTIONS -#define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (1) -#endif -#define MICROPY_PY_MATH_ISCLOSE (MICROPY_PY_MATH_SPECIAL_FUNCTIONS) -#define MICROPY_PY_CMATH (1) -#define MICROPY_PY_IO_IOBASE (1) -#define MICROPY_PY_IO_FILEIO (1) #define MICROPY_PY_GC_COLLECT_RETVAL (1) #ifndef MICROPY_STACKLESS @@ -146,25 +169,21 @@ #define MICROPY_STACKLESS_STRICT (0) #endif -#define MICROPY_PY_OS_STATVFS (1) +#define MICROPY_PY_UOS_INCLUDEFILE "ports/unix/moduos.c" +#define MICROPY_PY_UOS_ERRNO (1) +#define MICROPY_PY_UOS_GETENV_PUTENV_UNSETENV (1) +#define MICROPY_PY_UOS_SEP (1) +#define MICROPY_PY_UOS_SYSTEM (1) +#define MICROPY_PY_UOS_URANDOM (1) #define MICROPY_PY_UTIME (1) #define MICROPY_PY_UTIME_MP_HAL (1) -#define MICROPY_PY_UERRNO (1) -#define MICROPY_PY_UCTYPES (1) -#define MICROPY_PY_UZLIB (1) -#define MICROPY_PY_UJSON (1) -#define MICROPY_PY_URE (1) -#define MICROPY_PY_UHEAPQ (1) #define MICROPY_PY_UTIMEQ (1) -#define MICROPY_PY_UHASHLIB (1) +#define MICROPY_PY_USOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128) #if MICROPY_PY_USSL #define MICROPY_PY_UHASHLIB_MD5 (1) #define MICROPY_PY_UHASHLIB_SHA1 (1) #define MICROPY_PY_UCRYPTOLIB (1) #endif -#define MICROPY_PY_UBINASCII (1) -#define MICROPY_PY_UBINASCII_CRC32 (1) -#define MICROPY_PY_URANDOM (1) #ifndef MICROPY_PY_USELECT_POSIX #define MICROPY_PY_USELECT_POSIX (1) #endif @@ -203,73 +222,11 @@ extern const struct _mp_print_t mp_stderr_print; #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1) #define MICROPY_EMERGENCY_EXCEPTION_BUF_SIZE (256) -#define MICROPY_KBD_EXCEPTION (1) #define MICROPY_ASYNC_KBD_INTR (1) #define mp_type_fileio mp_type_vfs_posix_fileio #define mp_type_textio mp_type_vfs_posix_textio -extern const struct _mp_obj_module_t mp_module_machine; -extern const struct _mp_obj_module_t mp_module_os; -extern const struct _mp_obj_module_t mp_module_uos_vfs; -extern const struct _mp_obj_module_t mp_module_uselect; -extern const struct _mp_obj_module_t mp_module_time; -extern const struct _mp_obj_module_t mp_module_termios; -extern const struct _mp_obj_module_t mp_module_socket; -extern const struct _mp_obj_module_t mp_module_ffi; -extern const struct _mp_obj_module_t mp_module_jni; - -#if MICROPY_PY_UOS_VFS -#define MICROPY_PY_UOS_DEF { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos_vfs) }, -#else -#define MICROPY_PY_UOS_DEF { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_os) }, -#endif -#if MICROPY_PY_FFI -#define MICROPY_PY_FFI_DEF { MP_ROM_QSTR(MP_QSTR_ffi), MP_ROM_PTR(&mp_module_ffi) }, -#else -#define MICROPY_PY_FFI_DEF -#endif -#if MICROPY_PY_MACHINE -#define MICROPY_PY_MACHINE_DEF { MP_ROM_QSTR(MP_QSTR_umachine), MP_ROM_PTR(&mp_module_machine) }, -#else -#define MICROPY_PY_MACHINE_DEF -#endif -#if MICROPY_PY_JNI -#define MICROPY_PY_JNI_DEF { MP_ROM_QSTR(MP_QSTR_jni), MP_ROM_PTR(&mp_module_jni) }, -#else -#define MICROPY_PY_JNI_DEF -#endif -#if MICROPY_PY_UTIME -#define MICROPY_PY_UTIME_DEF { MP_ROM_QSTR(MP_QSTR_utime), MP_ROM_PTR(&mp_module_time) }, -#else -#define MICROPY_PY_UTIME_DEF -#endif -#if MICROPY_PY_TERMIOS -#define MICROPY_PY_TERMIOS_DEF { MP_ROM_QSTR(MP_QSTR_termios), MP_ROM_PTR(&mp_module_termios) }, -#else -#define MICROPY_PY_TERMIOS_DEF -#endif -#if MICROPY_PY_SOCKET -#define MICROPY_PY_SOCKET_DEF { MP_ROM_QSTR(MP_QSTR_usocket), MP_ROM_PTR(&mp_module_socket) }, -#else -#define MICROPY_PY_SOCKET_DEF -#endif -#if MICROPY_PY_USELECT_POSIX -#define MICROPY_PY_USELECT_DEF { MP_ROM_QSTR(MP_QSTR_uselect), MP_ROM_PTR(&mp_module_uselect) }, -#else -#define MICROPY_PY_USELECT_DEF -#endif - -#define MICROPY_PORT_BUILTIN_MODULES \ - MICROPY_PY_FFI_DEF \ - MICROPY_PY_JNI_DEF \ - MICROPY_PY_UTIME_DEF \ - MICROPY_PY_SOCKET_DEF \ - MICROPY_PY_MACHINE_DEF \ - MICROPY_PY_UOS_DEF \ - MICROPY_PY_USELECT_DEF \ - MICROPY_PY_TERMIOS_DEF \ - // type definitions for the specific machine // For size_t and ssize_t @@ -306,6 +263,17 @@ void mp_unix_mark_exec(void); #define MICROPY_FORCE_PLAT_ALLOC_EXEC (1) #endif +#ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC +// Support for seeding the random module on import. +#include +void mp_hal_get_random(size_t n, void *buf); +static inline unsigned long mp_urandom_seed_init(void) { + unsigned long r; + mp_hal_get_random(sizeof(r), &r); + return r; +} +#endif + #ifdef __linux__ // Can access physical memory using /dev/mem #define MICROPY_PLAT_DEV_MEM (1) @@ -324,14 +292,26 @@ void mp_unix_mark_exec(void); #endif #endif -#define MICROPY_PORT_BUILTINS \ - { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, - #define MP_STATE_PORT MP_STATE_VM +#if MICROPY_PY_BLUETOOTH +#if MICROPY_BLUETOOTH_BTSTACK +struct _mp_bluetooth_btstack_root_pointers_t; +#define MICROPY_BLUETOOTH_ROOT_POINTERS struct _mp_bluetooth_btstack_root_pointers_t *bluetooth_btstack_root_pointers; +#endif +#if MICROPY_BLUETOOTH_NIMBLE +struct _mp_bluetooth_nimble_root_pointers_t; +struct _mp_bluetooth_nimble_malloc_t; +#define MICROPY_BLUETOOTH_ROOT_POINTERS struct _mp_bluetooth_nimble_malloc_t *bluetooth_nimble_memory; struct _mp_bluetooth_nimble_root_pointers_t *bluetooth_nimble_root_pointers; +#endif +#else +#define MICROPY_BLUETOOTH_ROOT_POINTERS +#endif + #define MICROPY_PORT_ROOT_POINTERS \ const char *readline_hist[50]; \ void *mmap_region_head; \ + MICROPY_BLUETOOTH_ROOT_POINTERS \ // We need to provide a declaration/definition of alloca() // unless support for it is disabled. diff --git a/ports/unix/mpconfigport.mk b/ports/unix/mpconfigport.mk index 78a758b769e05..a0f654597b732 100644 --- a/ports/unix/mpconfigport.mk +++ b/ports/unix/mpconfigport.mk @@ -9,7 +9,8 @@ MICROPY_FORCE_32BIT = 0 MICROPY_USE_READLINE = 1 # btree module using Berkeley DB 1.xx -MICROPY_PY_BTREE = 1 +# CIRCUITPY: not present +MICROPY_PY_BTREE = 0 # _thread module using pthreads MICROPY_PY_THREAD = 1 @@ -39,4 +40,7 @@ MICROPY_PY_JNI = 0 # as submodules (currently affects only libffi). MICROPY_STANDALONE = 0 +# CIRCUITPY CIRCUITPY_ULAB = 1 +MICROPY_EMIT_NATIVE = 0 +CFLAGS += -DCIRCUITPY=1 diff --git a/ports/unix/mphalport.h b/ports/unix/mphalport.h index 9242bef1adb6b..e3c2a8035bc05 100644 --- a/ports/unix/mphalport.h +++ b/ports/unix/mphalport.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2015 Damien P. George + * Copyright (c) 2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -92,3 +92,13 @@ static inline void mp_hal_delay_us(mp_uint_t us) { #define RAISE_ERRNO(err_flag, error_val) \ { if (err_flag == -1) \ { mp_raise_OSError(error_val); } } + +void mp_hal_get_random(size_t n, void *buf); + +#if MICROPY_PY_BLUETOOTH +enum { + MP_HAL_MAC_BDADDR, +}; + +void mp_hal_get_mac(int idx, uint8_t buf[6]); +#endif diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c index 6a0ce59377ca1..6a267e723635c 100644 --- a/ports/unix/mpthreadport.c +++ b/ports/unix/mpthreadport.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd + * Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -53,12 +53,12 @@ #define THREAD_STACK_OVERFLOW_MARGIN (8192) // this structure forms a linked list, one node per active thread -typedef struct _thread_t { +typedef struct _mp_thread_t { pthread_t id; // system id of thread int ready; // whether the thread is ready and running void *arg; // thread Python args, a GC root pointer - struct _thread_t *next; -} thread_t; + struct _mp_thread_t *next; +} mp_thread_t; STATIC pthread_key_t tls_key; @@ -66,7 +66,7 @@ STATIC pthread_key_t tls_key; // Specifically for thread management, access to the linked list is one example. // But also, e.g. scheduler state. STATIC pthread_mutex_t thread_mutex; -STATIC thread_t *thread; +STATIC mp_thread_t *thread; // this is used to synchronise the signal handler of the thread // it's needed because we can't use any pthread calls in a signal handler @@ -119,7 +119,7 @@ void mp_thread_init(void) { pthread_mutex_init(&thread_mutex, &thread_mutex_attr); // create first entry in linked list of all threads - thread = malloc(sizeof(thread_t)); + thread = malloc(sizeof(mp_thread_t)); thread->id = pthread_self(); thread->ready = 1; thread->arg = NULL; @@ -143,7 +143,7 @@ void mp_thread_init(void) { void mp_thread_deinit(void) { mp_thread_unix_begin_atomic_section(); while (thread->next != NULL) { - thread_t *th = thread; + mp_thread_t *th = thread; thread = thread->next; pthread_cancel(th->id); free(th); @@ -165,7 +165,7 @@ void mp_thread_deinit(void) { // garbage collection and tracing these pointers. void mp_thread_gc_others(void) { mp_thread_unix_begin_atomic_section(); - for (thread_t *th = thread; th != NULL; th = th->next) { + for (mp_thread_t *th = thread; th != NULL; th = th->next) { gc_collect_root(&th->arg, 1); if (th->id == pthread_self()) { continue; @@ -192,9 +192,16 @@ void mp_thread_set_state(mp_state_thread_t *state) { } void mp_thread_start(void) { + // enable realtime priority if `-X realtime` command line parameter was set + #if defined(__APPLE__) + if (mp_thread_is_realtime_enabled) { + mp_thread_set_realtime(); + } + #endif + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); mp_thread_unix_begin_atomic_section(); - for (thread_t *th = thread; th != NULL; th = th->next) { + for (mp_thread_t *th = thread; th != NULL; th = th->next) { if (th->id == pthread_self()) { th->ready = 1; break; @@ -249,7 +256,7 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) { *stack_size -= THREAD_STACK_OVERFLOW_MARGIN; // add thread to linked list of all threads - thread_t *th = malloc(sizeof(thread_t)); + mp_thread_t *th = malloc(sizeof(mp_thread_t)); th->id = id; th->ready = 0; th->arg = arg; @@ -266,8 +273,8 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) { void mp_thread_finish(void) { mp_thread_unix_begin_atomic_section(); - thread_t *prev = NULL; - for (thread_t *th = thread; th != NULL; th = th->next) { + mp_thread_t *prev = NULL; + for (mp_thread_t *th = thread; th != NULL; th = th->next) { if (th->id == pthread_self()) { if (prev == NULL) { thread = th->next; @@ -310,3 +317,39 @@ void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) { } #endif // MICROPY_PY_THREAD + +// this is used even when MICROPY_PY_THREAD is disabled + +#if defined(__APPLE__) +#include +#include +#include +#include + +bool mp_thread_is_realtime_enabled; + +// based on https://developer.apple.com/library/archive/technotes/tn2169/_index.html +void mp_thread_set_realtime(void) { + mach_timebase_info_data_t timebase_info; + + mach_timebase_info(&timebase_info); + + const uint64_t NANOS_PER_MSEC = 1000000ULL; + double clock2abs = ((double)timebase_info.denom / (double)timebase_info.numer) * NANOS_PER_MSEC; + + thread_time_constraint_policy_data_t policy; + policy.period = 0; + policy.computation = (uint32_t)(5 * clock2abs); // 5 ms of work + policy.constraint = (uint32_t)(10 * clock2abs); + policy.preemptible = FALSE; + + int kr = thread_policy_set(pthread_mach_thread_np(pthread_self()), + THREAD_TIME_CONSTRAINT_POLICY, + (thread_policy_t)&policy, + THREAD_TIME_CONSTRAINT_POLICY_COUNT); + + if (kr != KERN_SUCCESS) { + mach_error("thread_policy_set:", kr); + } +} +#endif diff --git a/ports/unix/mpthreadport.h b/ports/unix/mpthreadport.h index 94edbe2f041cb..b365f200edf97 100644 --- a/ports/unix/mpthreadport.h +++ b/ports/unix/mpthreadport.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd + * Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,7 @@ */ #include +#include typedef pthread_mutex_t mp_thread_mutex_t; @@ -36,3 +37,9 @@ void mp_thread_gc_others(void); // Functions as a port-global lock for any code that must be serialised. void mp_thread_unix_begin_atomic_section(void); void mp_thread_unix_end_atomic_section(void); + +// for `-X realtime` command line option +#if defined(__APPLE__) +extern bool mp_thread_is_realtime_enabled; +void mp_thread_set_realtime(void); +#endif diff --git a/ports/unix/qstrdefsport.h b/ports/unix/qstrdefsport.h index 0c99d91c6e87f..8b827a8d64761 100644 --- a/ports/unix/qstrdefsport.h +++ b/ports/unix/qstrdefsport.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/unix/unix_mphal.c b/ports/unix/unix_mphal.c index 9d50652e39b0b..665d038c0d59c 100644 --- a/ports/unix/unix_mphal.c +++ b/ports/unix/unix_mphal.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2015 Damien P. George + * Copyright (c) 2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,10 +29,19 @@ #include #include #include +#include #include "py/mphal.h" #include "py/mpthread.h" #include "py/runtime.h" +#include "extmod/misc.h" + +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +#if __GLIBC_PREREQ(2, 25) +#include +#define _HAVE_GETRANDOM +#endif +#endif #ifndef _WIN32 #include @@ -86,6 +95,7 @@ void mp_hal_set_interrupt_char(char c) { } } +// CIRCUITPY bool mp_hal_is_interrupted(void) { return false; } @@ -116,7 +126,58 @@ void mp_hal_stdio_mode_orig(void) { #endif +#if MICROPY_PY_OS_DUPTERM +static int call_dupterm_read(size_t idx) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t read_m[3]; + mp_load_method(MP_STATE_VM(dupterm_objs[idx]), MP_QSTR_read, read_m); + read_m[2] = MP_OBJ_NEW_SMALL_INT(1); + mp_obj_t res = mp_call_method_n_kw(1, 0, read_m); + if (res == mp_const_none) { + return -2; + } + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len == 0) { + mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n"); + MP_STATE_VM(dupterm_objs[idx]) = MP_OBJ_NULL; + return -1; + } + nlr_pop(); + return *(byte *)bufinfo.buf; + } else { + // Temporarily disable dupterm to avoid infinite recursion + mp_obj_t save_term = MP_STATE_VM(dupterm_objs[idx]); + MP_STATE_VM(dupterm_objs[idx]) = NULL; + mp_printf(&mp_plat_print, "dupterm: "); + mp_obj_print_exception(&mp_plat_print, nlr.ret_val); + MP_STATE_VM(dupterm_objs[idx]) = save_term; + } + + return -1; +} +#endif + int mp_hal_stdin_rx_chr(void) { + #if MICROPY_PY_OS_DUPTERM + // TODO only support dupterm one slot at the moment + if (MP_STATE_VM(dupterm_objs[0]) != MP_OBJ_NULL) { + int c; + do { + c = call_dupterm_read(0); + } while (c == -2); + if (c == -1) { + goto main_term; + } + if (c == '\n') { + c = '\r'; + } + return c; + } +main_term:; + #endif + unsigned char c; ssize_t ret; MP_HAL_RETRY_SYSCALL(ret, read(STDIN_FILENO, &c, 1), {}); @@ -131,6 +192,9 @@ int mp_hal_stdin_rx_chr(void) { void mp_hal_stdout_tx_strn(const char *str, size_t len) { ssize_t ret; MP_HAL_RETRY_SYSCALL(ret, write(STDOUT_FILENO, str, len), {}); + #if MICROPY_PY_OS_DUPTERM + mp_uos_dupterm_tx_strn(str, len); + #endif } // cooked is same as uncooked because the terminal does some postprocessing @@ -185,3 +249,14 @@ void mp_hal_delay_ms(mp_uint_t ms) { usleep(ms * 1000); #endif } + +void mp_hal_get_random(size_t n, void *buf) { + #ifdef _HAVE_GETRANDOM + RAISE_ERRNO(getrandom(buf, n, 0), errno); + #else + int fd = open("/dev/urandom", O_RDONLY); + RAISE_ERRNO(fd, errno); + RAISE_ERRNO(read(fd, buf, n), errno); + close(fd); + #endif +} diff --git a/ports/unix/variants/coverage/frzmpy/frzmpy3.py b/ports/unix/variants/coverage/frzmpy/frzmpy3.py new file mode 100644 index 0000000000000..617fac5523b64 --- /dev/null +++ b/ports/unix/variants/coverage/frzmpy/frzmpy3.py @@ -0,0 +1,6 @@ +# Test freezing objects that may not be handled well by the build process. + +print("\\") +print("\nX") +print(repr("\x1b")) +print(b"\x00\xff") diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index 0c6e10aeae00f..5828cb5616d3c 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2013-2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,11 +27,20 @@ // This config enables almost all possible features such that it can be used // for coverage testing. +// Set base feature level. +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) + #define MICROPY_VFS (1) #define MICROPY_PY_UOS_VFS (1) +// Disable some features that come enabled by default with the feature level. +#define MICROPY_PY_BUILTINS_EXECFILE (0) +#define MICROPY_PY_SYS_STDIO_BUFFER (0) +#define MICROPY_PY_USELECT (0) + +// Enable additional features. #define MICROPY_DEBUG_PARSE_RULE_NAME (1) -#define MICROPY_OPT_MATH_FACTORIAL (1) +#define MICROPY_TRACKED_ALLOC (1) #define MICROPY_FLOAT_HIGH_QUALITY_HASH (1) #define MICROPY_ENABLE_SCHEDULER (1) #define MICROPY_READER_VFS (1) @@ -48,10 +57,12 @@ #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_MODULES (1) #define MICROPY_PY_SYS_GETSIZEOF (1) +#define MICROPY_PY_SYS_TRACEBACKLIMIT (1) #define MICROPY_PY_MATH_FACTORIAL (1) #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) #define MICROPY_PY_IO_BUFFEREDWRITER (1) #define MICROPY_PY_UASYNCIO (1) +#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (mp_urandom_seed_init()) #define MICROPY_PY_URE_DEBUG (1) #define MICROPY_PY_URE_MATCH_GROUPS (1) #define MICROPY_PY_URE_MATCH_SPAN_START_END (1) @@ -66,9 +77,3 @@ #define MICROPY_PY_UCRYPTOLIB (1) #define MICROPY_PY_UCRYPTOLIB_CTR (1) #define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (1) -#define MICROPY_CPYTHON_EXCEPTION_CHAIN (1) - -// use vfs's functions for import stat and builtin open -#define mp_import_stat mp_vfs_import_stat -#define mp_builtin_open mp_vfs_open -#define mp_builtin_open_obj mp_vfs_open_obj diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index 9289e9cb4dce0..656fd77289aff 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -8,6 +8,7 @@ CFLAGS += \ -Wformat -Wmissing-declarations -Wmissing-prototypes \ -Wold-style-definition -Wpointer-arith -Wshadow -Wuninitialized -Wunused-parameter \ -DMICROPY_UNIX_COVERAGE \ + -DMICROPY_CPYTHON_EXCEPTION_CHAIN=1 \ -DMODULE_CEXAMPLE_ENABLED=1 -DMODULE_CPPEXAMPLE_ENABLED=1 LDFLAGS += -fprofile-arcs -ftest-coverage diff --git a/ports/unix/variants/dev/mpconfigvariant.h b/ports/unix/variants/dev/mpconfigvariant.h index 54ad99323625b..61092394cd738 100644 --- a/ports/unix/variants/dev/mpconfigvariant.h +++ b/ports/unix/variants/dev/mpconfigvariant.h @@ -24,24 +24,16 @@ * THE SOFTWARE. */ -#define MICROPY_READER_VFS (1) +// Set base feature level. +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) + +// Disable some features that come enabled by default with the feature level. +#define MICROPY_PY_BUILTINS_EXECFILE (0) +#define MICROPY_PY_SYS_STDIO_BUFFER (0) +#define MICROPY_PY_USELECT (0) + +// Enable some additional features. #define MICROPY_REPL_EMACS_WORDS_MOVE (1) #define MICROPY_REPL_EMACS_EXTRA_WORDS_MOVE (1) -#define MICROPY_ENABLE_SCHEDULER (1) -#define MICROPY_VFS (1) -#define MICROPY_VFS_POSIX (1) - -#define MICROPY_PY_BUILTINS_HELP (1) -#define MICROPY_PY_BUILTINS_HELP_MODULES (1) #define MICROPY_PY_SYS_SETTRACE (1) -#define MICROPY_PY_UOS_VFS (1) -#define MICROPY_PY_URANDOM_EXTRA_FUNCS (1) - -#ifndef MICROPY_PY_UASYNCIO -#define MICROPY_PY_UASYNCIO (1) -#endif - -// Use vfs's functions for import stat and builtin open. -#define mp_import_stat mp_vfs_import_stat -#define mp_builtin_open mp_vfs_open -#define mp_builtin_open_obj mp_vfs_open_obj +#define MICROPY_PY_URANDOM_SEED_INIT_FUNC (mp_urandom_seed_init()) diff --git a/ports/unix/variants/dev/mpconfigvariant.mk b/ports/unix/variants/dev/mpconfigvariant.mk index 16d033c6cec65..91bd28da9bd85 100644 --- a/ports/unix/variants/dev/mpconfigvariant.mk +++ b/ports/unix/variants/dev/mpconfigvariant.mk @@ -2,6 +2,7 @@ PROG ?= micropython-dev FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py +MICROPY_ROM_TEXT_COMPRESSION = 1 MICROPY_VFS_FAT = 1 MICROPY_VFS_LFS1 = 1 MICROPY_VFS_LFS2 = 1 diff --git a/ports/unix/variants/fast/mpconfigvariant.h b/ports/unix/variants/fast/mpconfigvariant.h index ba9981db1be1a..8a531b056ab71 100644 --- a/ports/unix/variants/fast/mpconfigvariant.h +++ b/ports/unix/variants/fast/mpconfigvariant.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/unix/variants/freedos/mpconfigvariant.h b/ports/unix/variants/freedos/mpconfigvariant.h index 9e93661ddfde4..562c783ca35fb 100644 --- a/ports/unix/variants/freedos/mpconfigvariant.h +++ b/ports/unix/variants/freedos/mpconfigvariant.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2015 Damien P. George + * Copyright (c) 2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index 09dc37d1c3068..60d194b6a1f03 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2015 Damien P. George + * Copyright (c) 2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -44,6 +44,7 @@ #define MICROPY_MEM_STATS (0) #define MICROPY_DEBUG_PRINTERS (0) #define MICROPY_READER_POSIX (1) +#define MICROPY_READER_VFS (1) #define MICROPY_HELPER_REPL (1) #define MICROPY_HELPER_LEXER_UNIX (1) #define MICROPY_ENABLE_SOURCE_LINE (0) @@ -59,6 +60,8 @@ #define MICROPY_OPT_MAP_LOOKUP_CACHE (0) #define MICROPY_CAN_OVERRIDE_BUILTINS (0) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) +#define MICROPY_VFS (1) +#define MICROPY_VFS_POSIX (1) #define MICROPY_CPYTHON_COMPAT (0) #define MICROPY_PY_BUILTINS_BYTEARRAY (0) #define MICROPY_PY_BUILTINS_MEMORYVIEW (0) @@ -98,18 +101,17 @@ #define MICROPY_PY_UTIME (0) #define MICROPY_PY_UZLIB (0) #define MICROPY_PY_UJSON (0) +#define MICROPY_PY_UOS (1) #define MICROPY_PY_URE (0) #define MICROPY_PY_UHEAPQ (0) #define MICROPY_PY_UHASHLIB (0) #define MICROPY_PY_UBINASCII (0) -extern const struct _mp_obj_module_t mp_module_os; - -#define MICROPY_PORT_BUILTIN_MODULES \ - { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_os) }, \ - #define MICROPY_PORT_ROOT_POINTERS \ +#define mp_type_fileio mp_type_vfs_posix_fileio +#define mp_type_textio mp_type_vfs_posix_textio + ////////////////////////////////////////// // Do not change anything beyond this line ////////////////////////////////////////// diff --git a/ports/unix/variants/minimal/mpconfigvariant.mk b/ports/unix/variants/minimal/mpconfigvariant.mk index 84343557aa861..ec3b21c0b979c 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.mk +++ b/ports/unix/variants/minimal/mpconfigvariant.mk @@ -3,6 +3,7 @@ PROG = micropython-minimal FROZEN_MANIFEST = +MICROPY_ROM_TEXT_COMPRESSION = 1 MICROPY_PY_BTREE = 0 MICROPY_PY_FFI = 0 MICROPY_PY_SOCKET = 0 diff --git a/ports/unix/variants/standard/mpconfigvariant.h b/ports/unix/variants/standard/mpconfigvariant.h index 3cdcfa8e9b8c9..1ec46ef92d352 100644 --- a/ports/unix/variants/standard/mpconfigvariant.h +++ b/ports/unix/variants/standard/mpconfigvariant.h @@ -24,5 +24,22 @@ * THE SOFTWARE. */ -#define MICROPY_PY_BUILTINS_HELP (1) -#define MICROPY_PY_BUILTINS_HELP_MODULES (1) +// Set base feature level. +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) + +// Disable some features that come enabled by default with the feature level. +#define MICROPY_OPT_MPZ_BITWISE (0) +#define MICROPY_OPT_MATH_FACTORIAL (0) +#define MICROPY_MODULE_ATTR_DELEGATION (0) +#define MICROPY_MODULE_BUILTIN_INIT (0) +#define MICROPY_ENABLE_SCHEDULER (0) +#define MICROPY_PY_BUILTINS_EXECFILE (0) +#define MICROPY_PY_MATH_CONSTANTS (0) +#define MICROPY_PY_MATH_FACTORIAL (0) +#define MICROPY_PY_SYS_PS1_PS2 (0) +#define MICROPY_PY_SYS_STDIO_BUFFER (0) +#define MICROPY_PY_USELECT (0) +#define MICROPY_PY_UASYNCIO (0) +#define MICROPY_PY_URE_SUB (0) +#define MICROPY_PY_URANDOM_EXTRA_FUNCS (0) +#define MICROPY_PY_FRAMEBUF (0) diff --git a/py/argcheck.c b/py/argcheck.c index 8a4419f88ff07..c3bde804d441f 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/asmarm.c b/py/asmarm.c index 3b637d34ef06b..42724e4d4b37c 100644 --- a/py/asmarm.c +++ b/py/asmarm.c @@ -4,7 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2014 Fabian Vogt - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -304,6 +304,11 @@ void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn) { emit_al(as, 0x1d000b0 | (rn << 16) | (rd << 12)); } +void asm_arm_ldrh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) { + // ldrh rd, [rn, #off] + emit_al(as, 0x1f000b0 | (rn << 16) | (rd << 12) | ((byte_offset & 0xf0) << 4) | (byte_offset & 0xf)); +} + void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn) { // ldrb rd, [rn] emit_al(as, 0x5d00000 | (rn << 16) | (rd << 12)); diff --git a/py/asmarm.h b/py/asmarm.h index cab4de79c25a8..ed8dc5f039219 100644 --- a/py/asmarm.h +++ b/py/asmarm.h @@ -4,7 +4,7 @@ * The MIT License (MIT) * * Copyright (c) 2014 Fabian Vogt - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -109,6 +109,7 @@ void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs); // memory void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn, uint byte_offset); void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn); +void asm_arm_ldrh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset); void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn); void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm, uint byte_offset); void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm); @@ -203,6 +204,7 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src); #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset)) #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_arm_ldrb_reg_reg((as), (reg_dest), (reg_base)) #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_arm_ldrh_reg_reg((as), (reg_dest), (reg_base)) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_arm_ldrh_reg_reg_offset((as), (reg_dest), (reg_base), 2 * (uint16_offset)) #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 0) #define ASM_STORE_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0) diff --git a/py/asmbase.c b/py/asmbase.c index ff1dd80ebe3b4..4a3fd089cb241 100644 --- a/py/asmbase.c +++ b/py/asmbase.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -61,7 +61,8 @@ void mp_asm_base_start_pass(mp_asm_base_t *as, int pass) { // all functions must go through this one to emit bytes // if as->pass < MP_ASM_PASS_EMIT, then this function just counts the number // of bytes needed and returns NULL, and callers should not store any data -uint8_t *mp_asm_base_get_cur_to_write_bytes(mp_asm_base_t *as, size_t num_bytes_to_write) { +uint8_t *mp_asm_base_get_cur_to_write_bytes(void *as_in, size_t num_bytes_to_write) { + mp_asm_base_t *as = as_in; uint8_t *c = NULL; if (as->pass == MP_ASM_PASS_EMIT) { assert(as->code_offset + num_bytes_to_write <= as->code_size); diff --git a/py/asmbase.h b/py/asmbase.h index f2932d6e20712..960be7685f5d4 100644 --- a/py/asmbase.h +++ b/py/asmbase.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,7 +45,7 @@ typedef struct _mp_asm_base_t { void mp_asm_base_init(mp_asm_base_t *as, size_t max_num_labels); void mp_asm_base_deinit(mp_asm_base_t *as, bool free_code); void mp_asm_base_start_pass(mp_asm_base_t *as, int pass); -uint8_t *mp_asm_base_get_cur_to_write_bytes(mp_asm_base_t *as, size_t num_bytes_to_write); +uint8_t *mp_asm_base_get_cur_to_write_bytes(void *as, size_t num_bytes_to_write); void mp_asm_base_label_assign(mp_asm_base_t *as, size_t label); void mp_asm_base_align(mp_asm_base_t *as, unsigned int align); void mp_asm_base_data(mp_asm_base_t *as, unsigned int bytesize, uintptr_t val); diff --git a/py/asmthumb.c b/py/asmthumb.c index 1b1923370b144..49574c43a7f1c 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,9 +34,25 @@ #if MICROPY_EMIT_THUMB || MICROPY_EMIT_INLINE_THUMB #include "py/mpstate.h" -#include "py/persistentcode.h" #include "py/asmthumb.h" +#ifdef _MSC_VER +#include + +static uint32_t mp_clz(uint32_t x) { + unsigned long lz = 0; + return _BitScanReverse(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; +} + +static uint32_t mp_ctz(uint32_t x) { + unsigned long tz = 0; + return _BitScanForward(&tz, x) ? tz : 0; +} +#else +#define mp_clz(x) __builtin_clz(x) +#define mp_ctz(x) __builtin_ctz(x) +#endif + #define UNSIGNED_FIT5(x) ((uint32_t)(x) < 32) #define UNSIGNED_FIT7(x) ((uint32_t)(x) < 128) #define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0) @@ -46,7 +62,6 @@ #define SIGNED_FIT12(x) (((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800) #define SIGNED_FIT23(x) (((x) & 0xffc00000) == 0) || (((x) & 0xffc00000) == 0xffc00000) -#if MICROPY_EMIT_THUMB_ARMV7M // Note: these actually take an imm12 but the high-bit is not encoded here #define OP_ADD_W_RRI_HI(reg_src) (0xf200 | (reg_src)) #define OP_ADD_W_RRI_LO(reg_dest, imm11) ((imm11 << 4 & 0x7000) | reg_dest << 8 | (imm11 & 0xff)) @@ -55,7 +70,9 @@ #define OP_LDR_W_HI(reg_base) (0xf8d0 | (reg_base)) #define OP_LDR_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12)) -#endif + +#define OP_LDRH_W_HI(reg_base) (0xf8b0 | (reg_base)) +#define OP_LDRH_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12)) static inline byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int n) { return mp_asm_base_get_cur_to_write_bytes(&as->base, n); @@ -158,21 +175,21 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) { } asm_thumb_op16(as, OP_PUSH_RLIST_LR(reglist)); if (stack_adjust > 0) { - #if MICROPY_EMIT_THUMB_ARMV7M - if (UNSIGNED_FIT7(stack_adjust)) { - asm_thumb_op16(as, OP_SUB_SP(stack_adjust)); + if (asm_thumb_allow_armv7m(as)) { + if (UNSIGNED_FIT7(stack_adjust)) { + asm_thumb_op16(as, OP_SUB_SP(stack_adjust)); + } else { + asm_thumb_op32(as, OP_SUB_W_RRI_HI(ASM_THUMB_REG_SP), OP_SUB_W_RRI_LO(ASM_THUMB_REG_SP, stack_adjust * 4)); + } } else { - asm_thumb_op32(as, OP_SUB_W_RRI_HI(ASM_THUMB_REG_SP), OP_SUB_W_RRI_LO(ASM_THUMB_REG_SP, stack_adjust * 4)); - } - #else - int adj = stack_adjust; - // we don't expect the stack_adjust to be massive - while (!UNSIGNED_FIT7(adj)) { - asm_thumb_op16(as, OP_SUB_SP(127)); - adj -= 127; + int adj = stack_adjust; + // we don't expect the stack_adjust to be massive + while (!UNSIGNED_FIT7(adj)) { + asm_thumb_op16(as, OP_SUB_SP(127)); + adj -= 127; + } + asm_thumb_op16(as, OP_SUB_SP(adj)); } - asm_thumb_op16(as, OP_SUB_SP(adj)); - #endif } as->push_reglist = reglist; as->stack_adjust = stack_adjust; @@ -180,21 +197,21 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) { void asm_thumb_exit(asm_thumb_t *as) { if (as->stack_adjust > 0) { - #if MICROPY_EMIT_THUMB_ARMV7M - if (UNSIGNED_FIT7(as->stack_adjust)) { - asm_thumb_op16(as, OP_ADD_SP(as->stack_adjust)); + if (asm_thumb_allow_armv7m(as)) { + if (UNSIGNED_FIT7(as->stack_adjust)) { + asm_thumb_op16(as, OP_ADD_SP(as->stack_adjust)); + } else { + asm_thumb_op32(as, OP_ADD_W_RRI_HI(ASM_THUMB_REG_SP), OP_ADD_W_RRI_LO(ASM_THUMB_REG_SP, as->stack_adjust * 4)); + } } else { - asm_thumb_op32(as, OP_ADD_W_RRI_HI(ASM_THUMB_REG_SP), OP_ADD_W_RRI_LO(ASM_THUMB_REG_SP, as->stack_adjust * 4)); - } - #else - int adj = as->stack_adjust; - // we don't expect the stack_adjust to be massive - while (!UNSIGNED_FIT7(adj)) { - asm_thumb_op16(as, OP_ADD_SP(127)); - adj -= 127; + int adj = as->stack_adjust; + // we don't expect the stack_adjust to be massive + while (!UNSIGNED_FIT7(adj)) { + asm_thumb_op16(as, OP_ADD_SP(127)); + adj -= 127; + } + asm_thumb_op16(as, OP_ADD_SP(adj)); } - asm_thumb_op16(as, OP_ADD_SP(adj)); - #endif } asm_thumb_op16(as, OP_POP_RLIST_PC(as->push_reglist)); } @@ -248,27 +265,19 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { asm_thumb_op16(as, 0x4600 | op_lo); } -#if MICROPY_EMIT_THUMB_ARMV7M - // if loading lo half with movw, the i16 value will be zero extended into the r32 register! -size_t asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { +void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { assert(reg_dest < ASM_THUMB_REG_R15); - size_t loc = mp_asm_base_get_code_pos(&as->base); // mov[wt] reg_dest, #i16_src asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); - return loc; } -#else - -void asm_thumb_mov_rlo_i16(asm_thumb_t *as, uint rlo_dest, int i16_src) { +static void asm_thumb_mov_rlo_i16(asm_thumb_t *as, uint rlo_dest, int i16_src) { asm_thumb_mov_rlo_i8(as, rlo_dest, (i16_src >> 8) & 0xff); asm_thumb_lsl_rlo_rlo_i5(as, rlo_dest, rlo_dest, 8); asm_thumb_add_rlo_i8(as, rlo_dest, i16_src & 0xff); } -#endif - #define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff)) bool asm_thumb_b_n_label(asm_thumb_t *as, uint label) { @@ -281,7 +290,7 @@ bool asm_thumb_b_n_label(asm_thumb_t *as, uint label) { #define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff)) -// all these bit arithmetic need coverage testing! +// all these bit arithmetics need coverage testing! #define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 14) & 0x003f)) #define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff)) @@ -292,14 +301,12 @@ bool asm_thumb_bcc_nw_label(asm_thumb_t *as, int cond, uint label, bool wide) { if (!wide) { asm_thumb_op16(as, OP_BCC_N(cond, rel)); return as->base.pass != MP_ASM_PASS_EMIT || SIGNED_FIT9(rel); - } else { - #if MICROPY_EMIT_THUMB_ARMV7M + } else if (asm_thumb_allow_armv7m(as)) { asm_thumb_op32(as, OP_BCC_W_HI(cond, rel), OP_BCC_W_LO(rel)); return true; - #else + } else { // this method should not be called for ARMV6M return false; - #endif } } @@ -320,30 +327,30 @@ size_t asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32) { size_t loc = mp_asm_base_get_code_pos(&as->base); - #if MICROPY_EMIT_THUMB_ARMV7M - asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, reg_dest, i32); - asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVT, reg_dest, i32 >> 16); - #else - // should only be called with lo reg for ARMV6M - assert(reg_dest < ASM_THUMB_REG_R8); - - // sanity check that generated code is aligned - assert(!as->base.code_base || !(3u & (uintptr_t)as->base.code_base)); - - // basically: - // (nop) - // ldr reg_dest, _data - // b 1f - // _data: .word i32 - // 1: - if (as->base.code_offset & 2u) { - asm_thumb_op16(as, ASM_THUMB_OP_NOP); + if (asm_thumb_allow_armv7m(as)) { + asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, reg_dest, i32); + asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVT, reg_dest, i32 >> 16); + } else { + // should only be called with lo reg for ARMV6M + assert(reg_dest < ASM_THUMB_REG_R8); + + // sanity check that generated code is aligned + assert(!as->base.code_base || !(3u & (uintptr_t)as->base.code_base)); + + // basically: + // (nop) + // ldr reg_dest, _data + // b 1f + // _data: .word i32 + // 1: + if (as->base.code_offset & 2u) { + asm_thumb_op16(as, ASM_THUMB_OP_NOP); + } + asm_thumb_ldr_rlo_pcrel_i8(as, reg_dest, 0); + asm_thumb_op16(as, OP_B_N(2)); + asm_thumb_op16(as, i32 & 0xffff); + asm_thumb_op16(as, i32 >> 16); } - asm_thumb_ldr_rlo_pcrel_i8(as, reg_dest, 0); - asm_thumb_op16(as, OP_B_N(2)); - asm_thumb_op16(as, i32 & 0xffff); - asm_thumb_op16(as, i32 >> 16); - #endif return loc; } @@ -351,14 +358,13 @@ size_t asm_thumb_mov_reg_i32(asm_thumb_t *as, uint reg_dest, mp_uint_t i32) { void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) { if (reg_dest < 8 && UNSIGNED_FIT8(i32)) { asm_thumb_mov_rlo_i8(as, reg_dest, i32); - } else { - #if MICROPY_EMIT_THUMB_ARMV7M + } else if (asm_thumb_allow_armv7m(as)) { if (UNSIGNED_FIT16(i32)) { asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, reg_dest, i32); } else { asm_thumb_mov_reg_i32(as, reg_dest, i32); } - #else + } else { uint rlo_dest = reg_dest; assert(rlo_dest < ASM_THUMB_REG_R8); // should never be called for ARMV6M @@ -367,8 +373,8 @@ void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) { i32 = -i32; } - uint clz = __builtin_clz(i32); - uint ctz = i32 ? __builtin_ctz(i32) : 0; + uint clz = mp_clz(i32); + uint ctz = i32 ? mp_ctz(i32) : 0; assert(clz + ctz <= 32); if (clz + ctz >= 24) { asm_thumb_mov_rlo_i8(as, rlo_dest, (i32 >> ctz) & 0xff); @@ -386,7 +392,6 @@ void asm_thumb_mov_reg_i32_optimised(asm_thumb_t *as, uint reg_dest, int i32) { if (negate) { asm_thumb_neg_rlo_rlo(as, rlo_dest, rlo_dest); } - #endif } } @@ -429,62 +434,76 @@ void asm_thumb_mov_reg_pcrel(asm_thumb_t *as, uint rlo_dest, uint label) { mp_uint_t dest = get_label_dest(as, label); mp_int_t rel = dest - as->base.code_offset; rel |= 1; // to stay in Thumb state when jumping to this address - #if MICROPY_EMIT_THUMB_ARMV7M - rel -= 4 + 4; // adjust for mov_reg_i16 and then PC+4 prefetch of add_reg_reg - asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, rlo_dest, rel); // 4 bytes - #else - rel -= 8 + 4; // adjust for four instructions and then PC+4 prefetch of add_reg_reg - // 6 bytes - asm_thumb_mov_rlo_i16(as, rlo_dest, rel); - // 2 bytes - not always needed, but we want to keep the size the same - asm_thumb_sxth_rlo_rlo(as, rlo_dest, rlo_dest); - #endif + if (asm_thumb_allow_armv7m(as)) { + rel -= 6 + 4; // adjust for mov_reg_i16, sxth_rlo_rlo and then PC+4 prefetch of add_reg_reg + asm_thumb_mov_reg_i16(as, ASM_THUMB_OP_MOVW, rlo_dest, rel); // 4 bytes + asm_thumb_sxth_rlo_rlo(as, rlo_dest, rlo_dest); // 2 bytes + } else { + rel -= 8 + 4; // adjust for four instructions and then PC+4 prefetch of add_reg_reg + // 6 bytes + asm_thumb_mov_rlo_i16(as, rlo_dest, rel); + // 2 bytes - not always needed, but we want to keep the size the same + asm_thumb_sxth_rlo_rlo(as, rlo_dest, rlo_dest); + } asm_thumb_add_reg_reg(as, rlo_dest, ASM_THUMB_REG_R15); // 2 bytes } -#if MICROPY_EMIT_THUMB_ARMV7M +// ARMv7-M only static inline void asm_thumb_ldr_reg_reg_i12(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) { asm_thumb_op32(as, OP_LDR_W_HI(reg_base), OP_LDR_W_LO(reg_dest, word_offset * 4)); } -#endif + +// emits code for: reg_dest = reg_base + offset << offset_shift +static void asm_thumb_add_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint reg_base, uint offset, uint offset_shift) { + if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8) { + if (offset << offset_shift < 256) { + if (reg_dest != reg_base) { + asm_thumb_mov_reg_reg(as, reg_dest, reg_base); + } + asm_thumb_add_rlo_i8(as, reg_dest, offset << offset_shift); + } else if (UNSIGNED_FIT8(offset) && reg_dest != reg_base) { + asm_thumb_mov_rlo_i8(as, reg_dest, offset); + asm_thumb_lsl_rlo_rlo_i5(as, reg_dest, reg_dest, offset_shift); + asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_base); + } else if (reg_dest != reg_base) { + asm_thumb_mov_rlo_i16(as, reg_dest, offset << offset_shift); + asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_dest); + } else { + uint reg_other = reg_dest ^ 7; + asm_thumb_op16(as, OP_PUSH_RLIST((1 << reg_other))); + asm_thumb_mov_rlo_i16(as, reg_other, offset << offset_shift); + asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_other); + asm_thumb_op16(as, OP_POP_RLIST((1 << reg_other))); + } + } else { + assert(0); // should never be called for ARMV6M + } +} void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) { if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8 && UNSIGNED_FIT5(word_offset)) { asm_thumb_ldr_rlo_rlo_i5(as, reg_dest, reg_base, word_offset); - } else { - #if MICROPY_EMIT_THUMB_ARMV7M + } else if (asm_thumb_allow_armv7m(as)) { asm_thumb_ldr_reg_reg_i12(as, reg_dest, reg_base, word_offset); - #else - word_offset -= 31; - if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8) { - if (UNSIGNED_FIT8(word_offset) && (word_offset < 64 || reg_dest != reg_base)) { - if (word_offset < 64) { - if (reg_dest != reg_base) { - asm_thumb_mov_reg_reg(as, reg_dest, reg_base); - } - asm_thumb_add_rlo_i8(as, reg_dest, word_offset * 4); - } else { - asm_thumb_mov_rlo_i8(as, reg_dest, word_offset); - asm_thumb_lsl_rlo_rlo_i5(as, reg_dest, reg_dest, 2); - asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_base); - } - } else { - if (reg_dest != reg_base) { - asm_thumb_mov_rlo_i16(as, reg_dest, word_offset * 4); - asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_dest); - } else { - uint reg_other = reg_dest ^ 7; - asm_thumb_op16(as, OP_PUSH_RLIST((1 << reg_other))); - asm_thumb_mov_rlo_i16(as, reg_other, word_offset * 4); - asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_other); - asm_thumb_op16(as, OP_POP_RLIST((1 << reg_other))); - } - } - } else { - assert(0); // should never be called for ARMV6M - } + } else { + asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, word_offset - 31, 2); asm_thumb_ldr_rlo_rlo_i5(as, reg_dest, reg_dest, 31); - #endif + } +} + +// ARMv7-M only +static inline void asm_thumb_ldrh_reg_reg_i12(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset) { + asm_thumb_op32(as, OP_LDRH_W_HI(reg_base), OP_LDRH_W_LO(reg_dest, uint16_offset * 2)); +} + +void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset) { + if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8 && UNSIGNED_FIT5(uint16_offset)) { + asm_thumb_ldrh_rlo_rlo_i5(as, reg_dest, reg_base, uint16_offset); + } else if (asm_thumb_allow_armv7m(as)) { + asm_thumb_ldrh_reg_reg_i12(as, reg_dest, reg_base, uint16_offset); + } else { + asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, uint16_offset - 31, 1); + asm_thumb_ldrh_rlo_rlo_i5(as, reg_dest, reg_dest, 31); } } @@ -496,20 +515,21 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) { mp_uint_t dest = get_label_dest(as, label); mp_int_t rel = dest - as->base.code_offset; rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction + if (dest != (mp_uint_t)-1 && rel <= -4) { // is a backwards jump, so we know the size of the jump on the first pass // calculate rel assuming 12 bit relative jump if (SIGNED_FIT12(rel)) { asm_thumb_op16(as, OP_B_N(rel)); - } else { - goto large_jump; + return; } - } else { - // is a forwards jump, so need to assume it's large - large_jump: - #if MICROPY_EMIT_THUMB_ARMV7M + } + + // is a large backwards jump, or a forwards jump (that must be assumed large) + + if (asm_thumb_allow_armv7m(as)) { asm_thumb_op32(as, OP_BW_HI(rel), OP_BW_LO(rel)); - #else + } else { if (SIGNED_FIT12(rel)) { // this code path has to be the same number of instructions irrespective of rel asm_thumb_op16(as, OP_B_N(rel)); @@ -520,7 +540,6 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) { mp_raise_NotImplementedError(MP_ERROR_TEXT("native method too big")); } } - #endif } } @@ -528,24 +547,24 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { mp_uint_t dest = get_label_dest(as, label); mp_int_t rel = dest - as->base.code_offset; rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction + if (dest != (mp_uint_t)-1 && rel <= -4) { // is a backwards jump, so we know the size of the jump on the first pass // calculate rel assuming 9 bit relative jump if (SIGNED_FIT9(rel)) { asm_thumb_op16(as, OP_BCC_N(cond, rel)); - } else { - goto large_jump; + return; } - } else { - // is a forwards jump, so need to assume it's large - large_jump: - #if MICROPY_EMIT_THUMB_ARMV7M + } + + // is a large backwards jump, or a forwards jump (that must be assumed large) + + if (asm_thumb_allow_armv7m(as)) { asm_thumb_op32(as, OP_BCC_W_HI(cond, rel), OP_BCC_W_LO(rel)); - #else + } else { // reverse the sense of the branch to jump over a longer branch asm_thumb_op16(as, OP_BCC_N(cond ^ 1, 0)); asm_thumb_b_label(as, label); - #endif } } diff --git a/py/asmthumb.h b/py/asmthumb.h index ea48f7ebf35b2..8961b0f796109 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,6 +29,7 @@ #include #include "py/misc.h" #include "py/asmbase.h" +#include "py/persistentcode.h" #define ASM_THUMB_REG_R0 (0) #define ASM_THUMB_REG_R1 (1) @@ -70,6 +71,21 @@ typedef struct _asm_thumb_t { uint32_t stack_adjust; } asm_thumb_t; +#if MICROPY_DYNAMIC_COMPILER + +static inline bool asm_thumb_allow_armv7m(asm_thumb_t *as) { + return MP_NATIVE_ARCH_ARMV7M <= mp_dynamic_compiler.native_arch + && mp_dynamic_compiler.native_arch <= MP_NATIVE_ARCH_ARMV7EMDP; +} + +#else + +static inline bool asm_thumb_allow_armv7m(asm_thumb_t *as) { + return MICROPY_EMIT_THUMB_ARMV7M; +} + +#endif + static inline void asm_thumb_end_pass(asm_thumb_t *as) { (void)as; } @@ -263,8 +279,8 @@ static inline void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint static inline void asm_thumb_strb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint byte_offset) { asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER, rlo_src, rlo_base, byte_offset); } -static inline void asm_thumb_strh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint byte_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_STRH, rlo_src, rlo_base, byte_offset); +static inline void asm_thumb_strh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint uint16_offset) { + asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_STRH, rlo_src, rlo_base, uint16_offset); } static inline void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset) { asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_dest, rlo_base, word_offset); @@ -272,8 +288,8 @@ static inline void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint static inline void asm_thumb_ldrb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint byte_offset) { asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER, rlo_dest, rlo_base, byte_offset); } -static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint byte_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_LDRH, rlo_dest, rlo_base, byte_offset); +static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint uint16_offset) { + asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_LDRH, rlo_dest, rlo_base, uint16_offset); } static inline void asm_thumb_lsl_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_src, uint shift) { asm_thumb_format_1(as, ASM_THUMB_FORMAT_1_LSL, rlo_dest, rlo_src, shift); @@ -308,12 +324,7 @@ static inline void asm_thumb_sxth_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint r #define ASM_THUMB_OP_MOVT (0xf2c0) void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src); - -#if MICROPY_EMIT_THUMB_ARMV7M -size_t asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src); -#else -void asm_thumb_mov_rlo_i16(asm_thumb_t *as, uint rlo_dest, int i16_src); -#endif +void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src); // these return true if the destination is in range, false otherwise bool asm_thumb_b_n_label(asm_thumb_t *as, uint label); @@ -327,7 +338,8 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience void asm_thumb_mov_reg_pcrel(asm_thumb_t *as, uint rlo_dest, uint label); -void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint byte_offset); // convenience +void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset); // convenience +void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset); // convenience void asm_thumb_b_label(asm_thumb_t *as, uint label); // convenience: picks narrow or wide branch void asm_thumb_bcc_label(asm_thumb_t *as, int cc, uint label); // convenience: picks narrow or wide branch @@ -389,11 +401,6 @@ void asm_thumb_b_rel12(asm_thumb_t *as, int rel); #define ASM_MOV_LOCAL_REG(as, local_num, reg) asm_thumb_mov_local_reg((as), (local_num), (reg)) #define ASM_MOV_REG_IMM(as, reg_dest, imm) asm_thumb_mov_reg_i32_optimised((as), (reg_dest), (imm)) -#if MICROPY_EMIT_THUMB_ARMV7M -#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_thumb_mov_reg_i16((as), ASM_THUMB_OP_MOVW, (reg_dest), (imm)) -#else -#define ASM_MOV_REG_IMM_FIX_U16(as, reg_dest, imm) asm_thumb_mov_rlo_i16((as), (reg_dest), (imm)) -#endif #define ASM_MOV_REG_IMM_FIX_WORD(as, reg_dest, imm) asm_thumb_mov_reg_i32((as), (reg_dest), (imm)) #define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) asm_thumb_mov_reg_local((as), (reg_dest), (local_num)) #define ASM_MOV_REG_REG(as, reg_dest, reg_src) asm_thumb_mov_reg_reg((as), (reg_dest), (reg_src)) @@ -414,6 +421,7 @@ void asm_thumb_b_rel12(asm_thumb_t *as, int rel); #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_thumb_ldr_reg_reg_i12_optimised((as), (reg_dest), (reg_base), (word_offset)) #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrb_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrh_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_thumb_ldrh_reg_reg_i12_optimised((as), (reg_dest), (reg_base), (uint16_offset)) #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0) diff --git a/py/asmx64.c b/py/asmx64.c index 62df5c6d4ad79..5c923a523ca54 100644 --- a/py/asmx64.c +++ b/py/asmx64.c @@ -319,9 +319,7 @@ void asm_x64_mov_mem64_to_r64(asm_x64_t *as, int src_r64, int src_disp, int dest STATIC void asm_x64_lea_disp_to_r64(asm_x64_t *as, int src_r64, int src_disp, int dest_r64) { // use REX prefix for 64 bit operation - assert(src_r64 < 8); - assert(dest_r64 < 8); - asm_x64_write_byte_2(as, REX_PREFIX | REX_W, OPCODE_LEA_MEM_TO_R64); + asm_x64_write_byte_2(as, REX_PREFIX | REX_W | REX_R_FROM_R64(dest_r64) | REX_B_FROM_R64(src_r64), OPCODE_LEA_MEM_TO_R64); asm_x64_write_r64_disp(as, dest_r64, src_r64, src_disp); } diff --git a/py/asmx64.h b/py/asmx64.h index ec9a088f88ee2..a4eaa12984b9d 100644 --- a/py/asmx64.h +++ b/py/asmx64.h @@ -207,6 +207,7 @@ void asm_x64_call_ind(asm_x64_t *as, size_t fun_id, int temp_r32); #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x64_mov_mem64_to_r64((as), (reg_base), 8 * (word_offset), (reg_dest)) #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem8_to_r64zx((as), (reg_base), 0, (reg_dest)) #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 0, (reg_dest)) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 2 * (uint16_offset), (reg_dest)) #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem32_to_r64zx((as), (reg_base), 0, (reg_dest)) #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 0) diff --git a/py/asmx86.c b/py/asmx86.c index b44da76dab9be..4b0f8047f6eb7 100644 --- a/py/asmx86.c +++ b/py/asmx86.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * Copyright (c) 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/asmx86.h b/py/asmx86.h index a8fb4e3f9e511..af7bb84988a31 100644 --- a/py/asmx86.h +++ b/py/asmx86.h @@ -202,6 +202,7 @@ void asm_x86_call_ind(asm_x86_t *as, size_t fun_id, mp_uint_t n_args, int temp_r #define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x86_mov_mem32_to_r32((as), (reg_base), 4 * (word_offset), (reg_dest)) #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem8_to_r32zx((as), (reg_base), 0, (reg_dest)) #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem16_to_r32zx((as), (reg_base), 0, (reg_dest)) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_x86_mov_mem16_to_r32zx((as), (reg_base), 2 * (uint16_offset), (reg_dest)) #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem32_to_r32((as), (reg_base), 0, (reg_dest)) #define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 0) diff --git a/py/asmxtensa.c b/py/asmxtensa.c index fa53e8351c2b0..8ac914ec412a4 100644 --- a/py/asmxtensa.c +++ b/py/asmxtensa.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ #include #include -#include "py/mpconfig.h" +#include "py/runtime.h" // wrapper around everything in this file #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA || MICROPY_EMIT_XTENSAWIN @@ -232,21 +232,33 @@ void asm_xtensa_mov_reg_pcrel(asm_xtensa_t *as, uint reg_dest, uint label) { asm_xtensa_op_add_n(as, reg_dest, reg_dest, ASM_XTENSA_REG_A0); } -void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx) { - if (idx < 16) { - asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A0, ASM_XTENSA_REG_FUN_TABLE, idx); +void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint word_offset) { + if (word_offset < 16) { + asm_xtensa_op_l32i_n(as, reg_dest, reg_base, word_offset); + } else if (word_offset < 256) { + asm_xtensa_op_l32i(as, reg_dest, reg_base, word_offset); } else { - asm_xtensa_op_l32i(as, ASM_XTENSA_REG_A0, ASM_XTENSA_REG_FUN_TABLE, idx); + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow")); } - asm_xtensa_op_callx0(as, ASM_XTENSA_REG_A0); } -void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx) { - if (idx < 16) { - asm_xtensa_op_l32i_n(as, ASM_XTENSA_REG_A8, ASM_XTENSA_REG_FUN_TABLE_WIN, idx); +void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset) { + if (word_offset < 16) { + asm_xtensa_op_s32i_n(as, reg_src, reg_base, word_offset); + } else if (word_offset < 256) { + asm_xtensa_op_s32i(as, reg_src, reg_base, word_offset); } else { - asm_xtensa_op_l32i(as, ASM_XTENSA_REG_A8, ASM_XTENSA_REG_FUN_TABLE_WIN, idx); + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow")); } +} + +void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx) { + asm_xtensa_l32i_optimised(as, ASM_XTENSA_REG_A0, ASM_XTENSA_REG_FUN_TABLE, idx); + asm_xtensa_op_callx0(as, ASM_XTENSA_REG_A0); +} + +void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx) { + asm_xtensa_l32i_optimised(as, ASM_XTENSA_REG_A8, ASM_XTENSA_REG_FUN_TABLE_WIN, idx); asm_xtensa_op_callx8(as, ASM_XTENSA_REG_A8); } diff --git a/py/asmxtensa.h b/py/asmxtensa.h index 529bfa5f0cf98..60205f8f9c709 100644 --- a/py/asmxtensa.h +++ b/py/asmxtensa.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -278,6 +278,8 @@ void asm_xtensa_mov_local_reg(asm_xtensa_t *as, int local_num, uint reg_src); void asm_xtensa_mov_reg_local(asm_xtensa_t *as, uint reg_dest, int local_num); void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_num); void asm_xtensa_mov_reg_pcrel(asm_xtensa_t *as, uint reg_dest, uint label); +void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint word_offset); +void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset); void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx); void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx); @@ -393,12 +395,13 @@ void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx); #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_xtensa_op_sub((as), (reg_dest), (reg_dest), (reg_src)) #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_xtensa_op_mull((as), (reg_dest), (reg_dest), (reg_src)) -#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), (word_offset)) +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_l32i_optimised((as), (reg_dest), (reg_base), (word_offset)) #define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0) #define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), (uint16_offset)) #define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), 0) -#define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_op_s32i_n((as), (reg_dest), (reg_base), (word_offset)) +#define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_s32i_optimised((as), (reg_dest), (reg_base), (word_offset)) #define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s8i((as), (reg_src), (reg_base), 0) #define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s16i((as), (reg_src), (reg_base), 0) #define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s32i_n((as), (reg_src), (reg_base), 0) diff --git a/py/bc.c b/py/bc.c index e7ad43389a17d..ecd2f60879181 100644 --- a/py/bc.c +++ b/py/bc.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * Copyright (c) 2014 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,11 +29,9 @@ #include #include -#include "py/runtime.h" #include "py/bc0.h" #include "py/bc.h" - -#include "supervisor/shared/translate/translate.h" +#include "py/objfun.h" #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) @@ -42,7 +40,23 @@ #define DEBUG_printf(...) (void)0 #endif -#if !MICROPY_PERSISTENT_CODE +void mp_encode_uint(void *env, mp_encode_uint_allocator_t allocator, mp_uint_t val) { + // We store each 7 bits in a separate byte, and that's how many bytes needed + byte buf[MP_ENCODE_UINT_MAX_BYTES]; + byte *p = buf + sizeof(buf); + // We encode in little-ending order, but store in big-endian, to help decoding + do { + *--p = val & 0x7f; + val >>= 7; + } while (val != 0); + byte *c = allocator(env, buf + sizeof(buf) - p); + if (c != NULL) { + while (p != buf + sizeof(buf) - 1) { + *c++ = *p++ | 0x80; + } + *c = *p; + } +} mp_uint_t mp_decode_uint(const byte **ptr) { mp_uint_t unum = 0; @@ -74,8 +88,6 @@ const byte *mp_decode_uint_skip(const byte *ptr) { return ptr; } -#endif - STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, size_t given) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE // generic message, used also for other argument issues @@ -109,46 +121,36 @@ STATIC void dump_args(const mp_obj_t *a, size_t sz) { // On entry code_state should be allocated somewhere (stack/heap) and // contain the following valid entries: // - code_state->fun_bc should contain a pointer to the function object -// - code_state->ip should contain the offset in bytes from the pointer -// code_state->fun_bc->bytecode to the entry n_state (0 for bytecode, non-zero for native) -void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { +// - code_state->ip should contain a pointer to the beginning of the prelude +// - code_state->sp should be: &code_state->state[0] - 1 +// - code_state->n_state should be the number of objects in the local state +STATIC void mp_setup_code_state_helper(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { // This function is pretty complicated. It's main aim is to be efficient in speed and RAM // usage for the common case of positional only args. // get the function object that we want to set up (could be bytecode or native code) mp_obj_fun_bc_t *self = code_state->fun_bc; - // ip comes in as an offset into bytecode, so turn it into a true pointer - code_state->ip = self->bytecode + (size_t)code_state->ip; - - #if MICROPY_STACKLESS - code_state->prev = NULL; - #endif - - #if MICROPY_PY_SYS_SETTRACE - code_state->prev_state = NULL; - code_state->frame = NULL; - #endif - // Get cached n_state (rather than decode it again) size_t n_state = code_state->n_state; // Decode prelude size_t n_state_unused, n_exc_stack_unused, scope_flags, n_pos_args, n_kwonly_args, n_def_pos_args; MP_BC_PRELUDE_SIG_DECODE_INTO(code_state->ip, n_state_unused, n_exc_stack_unused, scope_flags, n_pos_args, n_kwonly_args, n_def_pos_args); + MP_BC_PRELUDE_SIZE_DECODE(code_state->ip); (void)n_state_unused; (void)n_exc_stack_unused; - code_state->sp = &code_state->state[0] - 1; + mp_obj_t *code_state_state = code_state->sp + 1; code_state->exc_sp_idx = 0; // zero out the local stack to begin with - memset(code_state->state, 0, n_state * sizeof(*code_state->state)); + memset(code_state_state, 0, n_state * sizeof(*code_state->state)); const mp_obj_t *kwargs = args + n_args; // var_pos_kw_args points to the stack where the var-args tuple, and var-kw dict, should go (if they are needed) - mp_obj_t *var_pos_kw_args = &code_state->state[n_state - 1 - n_pos_args - n_kwonly_args]; + mp_obj_t *var_pos_kw_args = &code_state_state[n_state - 1 - n_pos_args - n_kwonly_args]; // check positional arguments @@ -171,7 +173,7 @@ void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_a if (n_args >= (size_t)(n_pos_args - n_def_pos_args)) { // given enough arguments, but may need to use some default arguments for (size_t i = n_args; i < n_pos_args; i++) { - code_state->state[n_state - 1 - i] = self->extra_args[i - (n_pos_args - n_def_pos_args)]; + code_state_state[n_state - 1 - i] = self->extra_args[i - (n_pos_args - n_def_pos_args)]; } } else { fun_pos_args_mismatch(self, n_pos_args - n_def_pos_args, n_args); @@ -181,14 +183,14 @@ void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_a // copy positional args into state for (size_t i = 0; i < n_args; i++) { - code_state->state[n_state - 1 - i] = args[i]; + code_state_state[n_state - 1 - i] = args[i]; } // check keyword arguments if (n_kw != 0 || (scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) { DEBUG_printf("Initial args: "); - dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); + dump_args(code_state_state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); mp_obj_t dict = MP_OBJ_NULL; if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { @@ -196,26 +198,25 @@ void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_a *var_pos_kw_args = dict; } - // get pointer to arg_names array - const mp_obj_t *arg_names = (const mp_obj_t *)self->const_table; - for (size_t i = 0; i < n_kw; i++) { // the keys in kwargs are expected to be qstr objects mp_obj_t wanted_arg_name = kwargs[2 * i]; - if (MP_UNLIKELY(!mp_obj_is_qstr(wanted_arg_name))) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE - mp_raise_TypeError(MP_ERROR_TEXT("unexpected keyword argument")); - #else - mp_raise_TypeError(MP_ERROR_TEXT("keywords must be strings")); - #endif - } + + // get pointer to arg_names array + const uint8_t *arg_names = code_state->ip; + arg_names = mp_decode_uint_skip(arg_names); + for (size_t j = 0; j < n_pos_args + n_kwonly_args; j++) { - if (wanted_arg_name == arg_names[j]) { - if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) { - mp_raise_TypeError_varg( + qstr arg_qstr = mp_decode_uint(&arg_names); + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + arg_qstr = self->context->constants.qstr_table[arg_qstr]; + #endif + if (wanted_arg_name == MP_OBJ_NEW_QSTR(arg_qstr)) { + if (code_state_state[n_state - 1 - j] != MP_OBJ_NULL) { + mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("function got multiple values for argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name)); } - code_state->state[n_state - 1 - j] = kwargs[2 * i + 1]; + code_state_state[n_state - 1 - j] = kwargs[2 * i + 1]; goto continue2; } } @@ -224,7 +225,7 @@ void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_a #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("unexpected keyword argument")); #else - mp_raise_TypeError_varg( + mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("unexpected keyword argument '%q'"), MP_OBJ_QSTR_VALUE(wanted_arg_name)); #endif } @@ -233,10 +234,10 @@ void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_a } DEBUG_printf("Args with kws flattened: "); - dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); + dump_args(code_state_state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); // fill in defaults for positional args - mp_obj_t *d = &code_state->state[n_state - n_pos_args]; + mp_obj_t *d = &code_state_state[n_state - n_pos_args]; mp_obj_t *s = &self->extra_args[n_def_pos_args - 1]; for (size_t i = n_def_pos_args; i > 0; i--, d++, s--) { if (*d == MP_OBJ_NULL) { @@ -245,26 +246,34 @@ void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_a } DEBUG_printf("Args after filling default positional: "); - dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); + dump_args(code_state_state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); // Check that all mandatory positional args are specified - while (d < &code_state->state[n_state]) { + while (d < &code_state_state[n_state]) { if (*d++ == MP_OBJ_NULL) { - mp_raise_TypeError_varg( - MP_ERROR_TEXT("function missing required positional argument #%d"), &code_state->state[n_state] - d); + mp_raise_msg_varg(&mp_type_TypeError, + MP_ERROR_TEXT("function missing required positional argument #%d"), &code_state_state[n_state] - d); } } // Check that all mandatory keyword args are specified // Fill in default kw args if we have them + const uint8_t *arg_names = mp_decode_uint_skip(code_state->ip); + for (size_t i = 0; i < n_pos_args; i++) { + arg_names = mp_decode_uint_skip(arg_names); + } for (size_t i = 0; i < n_kwonly_args; i++) { - if (code_state->state[n_state - 1 - n_pos_args - i] == MP_OBJ_NULL) { + qstr arg_qstr = mp_decode_uint(&arg_names); + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + arg_qstr = self->context->constants.qstr_table[arg_qstr]; + #endif + if (code_state_state[n_state - 1 - n_pos_args - i] == MP_OBJ_NULL) { mp_map_elem_t *elem = NULL; if ((scope_flags & MP_SCOPE_FLAG_DEFKWARGS) != 0) { - elem = mp_map_lookup(&((mp_obj_dict_t *)MP_OBJ_TO_PTR(self->extra_args[n_def_pos_args]))->map, arg_names[n_pos_args + i], MP_MAP_LOOKUP); + elem = mp_map_lookup(&((mp_obj_dict_t *)MP_OBJ_TO_PTR(self->extra_args[n_def_pos_args]))->map, MP_OBJ_NEW_QSTR(arg_qstr), MP_MAP_LOOKUP); } if (elem != NULL) { - code_state->state[n_state - 1 - n_pos_args - i] = elem->value; + code_state_state[n_state - 1 - n_pos_args - i] = elem->value; } else { mp_raise_TypeError_varg( MP_ERROR_TEXT("function missing required keyword argument '%q'"), @@ -283,57 +292,49 @@ void PLACE_IN_ITCM(mp_setup_code_state)(mp_code_state_t * code_state, size_t n_a } } - // read the size part of the prelude - const byte *ip = code_state->ip; - MP_BC_PRELUDE_SIZE_DECODE(ip); - - // jump over code info (source file and line-number mapping) - ip += n_info; + // jump over code info (source file, argument names and line-number mapping) + const uint8_t *ip = code_state->ip + n_info; // bytecode prelude: initialise closed over variables for (; n_cell; --n_cell) { size_t local_num = *ip++; - code_state->state[n_state - 1 - local_num] = - mp_obj_new_cell(code_state->state[n_state - 1 - local_num]); + code_state_state[n_state - 1 - local_num] = + mp_obj_new_cell(code_state_state[n_state - 1 - local_num]); } - #if !MICROPY_PERSISTENT_CODE - // so bytecode is aligned - ip = MP_ALIGN(ip, sizeof(mp_uint_t)); - #endif - // now that we skipped over the prelude, set the ip for the VM code_state->ip = ip; DEBUG_printf("Calling: n_pos_args=%d, n_kwonly_args=%d\n", n_pos_args, n_kwonly_args); - dump_args(code_state->state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); - dump_args(code_state->state, n_state); + dump_args(code_state_state + n_state - n_pos_args - n_kwonly_args, n_pos_args + n_kwonly_args); + dump_args(code_state_state, n_state); } -#if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE - -// The following table encodes the number of bytes that a specific opcode -// takes up. Some opcodes have an extra byte, defined by MP_BC_MASK_EXTRA_BYTE. -uint mp_opcode_format(const byte *ip, size_t *opcode_size, bool count_var_uint) { - uint f = MP_BC_FORMAT(*ip); - const byte *ip_start = ip; - if (f == MP_BC_FORMAT_QSTR) { - ip += 3; - } else { - int extra_byte = (*ip & MP_BC_MASK_EXTRA_BYTE) == 0; - ip += 1; - if (f == MP_BC_FORMAT_VAR_UINT) { - if (count_var_uint) { - while ((*ip++ & 0x80) != 0) { - } - } - } else if (f == MP_BC_FORMAT_OFFSET) { - ip += 2; - } - ip += extra_byte; - } - *opcode_size = ip - ip_start; - return f; +// On entry code_state should be allocated somewhere (stack/heap) and +// contain the following valid entries: +// - code_state->fun_bc should contain a pointer to the function object +// - code_state->n_state should be the number of objects in the local state +void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { + code_state->ip = code_state->fun_bc->bytecode; + code_state->sp = &code_state->state[0] - 1; + #if MICROPY_STACKLESS + code_state->prev = NULL; + #endif + #if MICROPY_PY_SYS_SETTRACE + code_state->prev_state = NULL; + code_state->frame = NULL; + #endif + mp_setup_code_state_helper(code_state, n_args, n_kw, args); } -#endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE +#if MICROPY_EMIT_NATIVE +// On entry code_state should be allocated somewhere (stack/heap) and +// contain the following valid entries: +// - code_state->fun_bc should contain a pointer to the function object +// - code_state->ip should contain a pointer to the beginning of the prelude +// - code_state->n_state should be the number of objects in the local state +void mp_setup_code_state_native(mp_code_state_native_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args) { + code_state->sp = &code_state->state[0] - 1; + mp_setup_code_state_helper((mp_code_state_t *)code_state, n_args, n_kw, args); +} +#endif diff --git a/py/bc.h b/py/bc.h index eeccc3412f00c..d620be8e824e2 100644 --- a/py/bc.h +++ b/py/bc.h @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,6 @@ #define MICROPY_INCLUDED_PY_BC_H #include "py/runtime.h" -#include "py/objfun.h" // bytecode layout: // @@ -50,7 +49,9 @@ // // source info section: // simple_name : var qstr -// source_file : var qstr +// argname0 : var qstr +// ... : var qstr +// argnameN : var qstr N = num_pos_args + num_kwonly_args - 1 // // // closure section: @@ -58,19 +59,16 @@ // ... : byte // local_numN : byte N = n_cells-1 // -// only needed if bytecode contains pointers -// // // // // constant table layout: // -// argname0 : obj (qstr) -// ... : obj (qstr) -// argnameN : obj (qstr) N = num_pos_args + num_kwonly_args // const0 : obj // constN : obj +#define MP_ENCODE_UINT_MAX_BYTES ((MP_BYTES_PER_OBJ_WORD * 8 + 6) / 7) + #define MP_BC_PRELUDE_SIG_ENCODE(S, E, scope, out_byte, out_env) \ do { \ /*// Get values to store in prelude */ \ @@ -187,9 +185,9 @@ typedef struct _mp_bytecode_prelude_t { uint n_pos_args; uint n_kwonly_args; uint n_def_pos_args; - qstr qstr_block_name; - qstr qstr_source_file; + qstr qstr_block_name_idx; const byte *line_info; + const byte *line_info_top; const byte *opcodes; } mp_bytecode_prelude_t; @@ -203,12 +201,46 @@ typedef struct _mp_exc_stack_t { mp_obj_base_t *prev_exc; } mp_exc_stack_t; +// Constants associated with a module, to interface bytecode with runtime. +typedef struct _mp_module_constants_t { + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + qstr_short_t *qstr_table; + #else + qstr source_file; + #endif + mp_obj_t *obj_table; +} mp_module_constants_t; + +// State associated with a module. +typedef struct _mp_module_context_t { + mp_obj_module_t module; + mp_module_constants_t constants; +} mp_module_context_t; + +// Outer level struct defining a compiled module. +typedef struct _mp_compiled_module_t { + const mp_module_context_t *context; + const struct _mp_raw_code_t *rc; + #if MICROPY_PERSISTENT_CODE_SAVE + bool has_native; + size_t n_qstr; + size_t n_obj; + #endif +} mp_compiled_module_t; + +// Outer level struct defining a frozen module. +typedef struct _mp_frozen_module_t { + const mp_module_constants_t constants; + const struct _mp_raw_code_t *rc; +} mp_frozen_module_t; + +// State for an executing function. typedef struct _mp_code_state_t { // The fun_bc entry points to the underlying function object that is being executed. // It is needed to access the start of bytecode and the const_table. // It is also needed to prevent the GC from reclaiming the bytecode during execution, // because the ip pointer below will always point to the interior of the bytecode. - mp_obj_fun_bc_t *fun_bc; + struct _mp_obj_fun_bc_t *fun_bc; const byte *ip; mp_obj_t *sp; uint16_t n_state; @@ -227,17 +259,37 @@ typedef struct _mp_code_state_t { // mp_exc_stack_t exc_state[0]; } mp_code_state_t; +// State for an executing native function (based on mp_code_state_t). +typedef struct _mp_code_state_native_t { + struct _mp_obj_fun_bc_t *fun_bc; + const byte *ip; + mp_obj_t *sp; + uint16_t n_state; + uint16_t exc_sp_idx; + mp_obj_dict_t *old_globals; + mp_obj_t state[0]; +} mp_code_state_native_t; + +// Allocator may return NULL, in which case data is not stored (can be used to compute size). +typedef uint8_t *(*mp_encode_uint_allocator_t)(void *env, size_t nbytes); + +void mp_encode_uint(void *env, mp_encode_uint_allocator_t allocator, mp_uint_t val); mp_uint_t mp_decode_uint(const byte **ptr); mp_uint_t mp_decode_uint_value(const byte *ptr); const byte *mp_decode_uint_skip(const byte *ptr); -mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc); +mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, +#ifndef __cplusplus + volatile +#endif + mp_obj_t inject_exc); mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, size_t n_args, size_t n_kw, const mp_obj_t *args); void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args); -void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *code, mp_uint_t len, const mp_uint_t *const_table); -void mp_bytecode_print2(const mp_print_t *print, const byte *code, size_t len, const mp_uint_t *const_table); -const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip); -#define mp_bytecode_print_inst(print, code, const_table) mp_bytecode_print2(print, code, 1, const_table) +void mp_setup_code_state_native(mp_code_state_native_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args); +void mp_bytecode_print(const mp_print_t *print, const struct _mp_raw_code_t *rc, const mp_module_constants_t *cm); +void mp_bytecode_print2(const mp_print_t *print, const byte *ip, size_t len, struct _mp_raw_code_t *const *child_table, const mp_module_constants_t *cm); +const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip_start, const byte *ip, struct _mp_raw_code_t *const *child_table, const mp_module_constants_t *cm); +#define mp_bytecode_print_inst(print, code, x_table) mp_bytecode_print2(print, code, 1, x_table) // Helper macros to access pointer with least significant bits holding flags #define MP_TAGPTR_PTR(x) ((void *)((uintptr_t)(x) & ~((uintptr_t)3))) @@ -245,16 +297,26 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip); #define MP_TAGPTR_TAG1(x) ((uintptr_t)(x) & 2) #define MP_TAGPTR_MAKE(ptr, tag) ((void *)((uintptr_t)(ptr) | (tag))) -#if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE - -uint mp_opcode_format(const byte *ip, size_t *opcode_size, bool count_var_uint); - -#endif +static inline void mp_module_context_alloc_tables(mp_module_context_t *context, size_t n_qstr, size_t n_obj) { + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + size_t nq = (n_qstr * sizeof(qstr_short_t) + sizeof(mp_uint_t) - 1) / sizeof(mp_uint_t); + size_t no = n_obj; + mp_uint_t *mem = m_new(mp_uint_t, nq + no); + context->constants.qstr_table = (qstr_short_t *)mem; + context->constants.obj_table = (mp_obj_t *)(mem + nq); + #else + if (n_obj == 0) { + context->constants.obj_table = NULL; + } else { + context->constants.obj_table = m_new(mp_obj_t, n_obj); + } + #endif +} -static inline size_t mp_bytecode_get_source_line(const byte *line_info, size_t bc_offset) { +static inline size_t mp_bytecode_get_source_line(const byte *line_info, const byte *line_info_top, size_t bc_offset) { size_t source_line = 1; - size_t c; - while ((c = *line_info)) { + while (line_info < line_info_top) { + size_t c = *line_info; size_t b, l; if ((c & 0x80) == 0) { // 0b0LLBBBBB encoding diff --git a/py/bc0.h b/py/bc0.h index 500dee5e7fdbf..a4a0acf9377ae 100644 --- a/py/bc0.h +++ b/py/bc0.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,6 +28,18 @@ // MicroPython bytecode opcodes, grouped based on the format of the opcode +// All opcodes are encoded as a byte with an optional argument. Arguments are +// variable-length encoded so they can be as small as possible. The possible +// encodings for arguments are (ip[0] is the opcode): +// +// - unsigned relative bytecode offset: +// - if ip[1] high bit is clear then: arg = ip[1] +// - if ip[1] high bit is set then: arg = ip[1] & 0x7f | ip[2] << 7 +// +// - signed relative bytecode offset: +// - if ip[1] high bit is clear then: arg = ip[1] - 0x40 +// - if ip[1] high bit is set then: arg = (ip[1] & 0x7f | ip[2] << 7) - 0x4000 + #define MP_BC_MASK_FORMAT (0xf0) #define MP_BC_MASK_EXTRA_BYTE (0x9e) @@ -101,17 +113,17 @@ #define MP_BC_ROT_TWO (MP_BC_BASE_BYTE_O + 0x0a) #define MP_BC_ROT_THREE (MP_BC_BASE_BYTE_O + 0x0b) -#define MP_BC_JUMP (MP_BC_BASE_JUMP_E + 0x02) // rel byte code offset, 16-bit signed, in excess -#define MP_BC_POP_JUMP_IF_TRUE (MP_BC_BASE_JUMP_E + 0x03) // rel byte code offset, 16-bit signed, in excess -#define MP_BC_POP_JUMP_IF_FALSE (MP_BC_BASE_JUMP_E + 0x04) // rel byte code offset, 16-bit signed, in excess -#define MP_BC_JUMP_IF_TRUE_OR_POP (MP_BC_BASE_JUMP_E + 0x05) // rel byte code offset, 16-bit signed, in excess -#define MP_BC_JUMP_IF_FALSE_OR_POP (MP_BC_BASE_JUMP_E + 0x06) // rel byte code offset, 16-bit signed, in excess -#define MP_BC_UNWIND_JUMP (MP_BC_BASE_JUMP_E + 0x00) // rel byte code offset, 16-bit signed, in excess; then a byte -#define MP_BC_SETUP_WITH (MP_BC_BASE_JUMP_E + 0x07) // rel byte code offset, 16-bit unsigned -#define MP_BC_SETUP_EXCEPT (MP_BC_BASE_JUMP_E + 0x08) // rel byte code offset, 16-bit unsigned -#define MP_BC_SETUP_FINALLY (MP_BC_BASE_JUMP_E + 0x09) // rel byte code offset, 16-bit unsigned -#define MP_BC_POP_EXCEPT_JUMP (MP_BC_BASE_JUMP_E + 0x0a) // rel byte code offset, 16-bit unsigned -#define MP_BC_FOR_ITER (MP_BC_BASE_JUMP_E + 0x0b) // rel byte code offset, 16-bit unsigned +#define MP_BC_UNWIND_JUMP (MP_BC_BASE_JUMP_E + 0x00) // signed relative bytecode offset; then a byte +#define MP_BC_JUMP (MP_BC_BASE_JUMP_E + 0x02) // signed relative bytecode offset +#define MP_BC_POP_JUMP_IF_TRUE (MP_BC_BASE_JUMP_E + 0x03) // signed relative bytecode offset +#define MP_BC_POP_JUMP_IF_FALSE (MP_BC_BASE_JUMP_E + 0x04) // signed relative bytecode offset +#define MP_BC_JUMP_IF_TRUE_OR_POP (MP_BC_BASE_JUMP_E + 0x05) // unsigned relative bytecode offset +#define MP_BC_JUMP_IF_FALSE_OR_POP (MP_BC_BASE_JUMP_E + 0x06) // unsigned relative bytecode offset +#define MP_BC_SETUP_WITH (MP_BC_BASE_JUMP_E + 0x07) // unsigned relative bytecode offset +#define MP_BC_SETUP_EXCEPT (MP_BC_BASE_JUMP_E + 0x08) // unsigned relative bytecode offset +#define MP_BC_SETUP_FINALLY (MP_BC_BASE_JUMP_E + 0x09) // unsigned relative bytecode offset +#define MP_BC_POP_EXCEPT_JUMP (MP_BC_BASE_JUMP_E + 0x0a) // unsigned relative bytecode offset +#define MP_BC_FOR_ITER (MP_BC_BASE_JUMP_E + 0x0b) // unsigned relative bytecode offset #define MP_BC_WITH_CLEANUP (MP_BC_BASE_BYTE_O + 0x0c) #define MP_BC_END_FINALLY (MP_BC_BASE_BYTE_O + 0x0d) #define MP_BC_GET_ITER (MP_BC_BASE_BYTE_O + 0x0e) diff --git a/py/binary.c b/py/binary.c index 439993c0f738c..60a74d616257f 100644 --- a/py/binary.c +++ b/py/binary.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky - * SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George + * Copyright (c) 2014-2017 Paul Sokolovsky + * Copyright (c) 2014-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -217,6 +217,7 @@ long long mp_binary_get_int(size_t size, bool is_signed, bool big_endian, const val = -1; } for (uint i = 0; i < size; i++) { + // CIRCUITPY fix val *= 256; val |= *src; src += delta; diff --git a/py/binary.h b/py/binary.h index 9fade810f8b4f..5c645bcaaa9c2 100644 --- a/py/binary.h +++ b/py/binary.h @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2014-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/builtin.h b/py/builtin.h index 4fa4b08f9db46..ab228278a7363 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,8 +28,43 @@ #include "py/obj.h" -mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args); +typedef enum { + MP_IMPORT_STAT_NO_EXIST, + MP_IMPORT_STAT_DIR, + MP_IMPORT_STAT_FILE, +} mp_import_stat_t; + +#if MICROPY_VFS + +// Delegate to the VFS for import stat and builtin open. + +#define mp_builtin_open_obj mp_vfs_open_obj + +mp_import_stat_t mp_vfs_import_stat(const char *path); +mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); + +MP_DECLARE_CONST_FUN_OBJ_KW(mp_vfs_open_obj); + +static inline mp_import_stat_t mp_import_stat(const char *path) { + return mp_vfs_import_stat(path); +} + +static inline mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { + return mp_vfs_open(n_args, args, kwargs); +} + +#else + +// A port can provide implementations of these functions. +mp_import_stat_t mp_import_stat(const char *path); mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); + +// A port can provide this object. +MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj); + +#endif + +mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args); mp_obj_t mp_micropython_mem_info(size_t n_args, const mp_obj_t *args); MP_DECLARE_CONST_FUN_OBJ_VAR(mp_builtin___build_class___obj); @@ -76,9 +111,7 @@ MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_repr_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_round_obj); MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj); -// Defined by a port, but declared here for simplicity MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj); -MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj); MP_DECLARE_CONST_FUN_OBJ_2(mp_namedtuple_obj); diff --git a/py/builtinevex.c b/py/builtinevex.c index 46d4a1277a274..b6b27c2a67726 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -56,7 +56,7 @@ STATIC mp_obj_t code_execute(mp_obj_code_t *self, mp_obj_dict_t *globals, mp_obj // the correct one if (mp_obj_is_type(self->module_fun, &mp_type_fun_bc)) { mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(self->module_fun); - fun_bc->globals = globals; + ((mp_module_context_t *)fun_bc->context)->module.globals = globals; } // execute code @@ -105,8 +105,7 @@ STATIC mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) { mp_raise_ValueError(MP_ERROR_TEXT("bad compile mode")); } - mp_obj_code_t *code = m_new_obj(mp_obj_code_t); - code->base.type = &mp_type_code; + mp_obj_code_t *code = mp_obj_malloc(mp_obj_code_t, &mp_type_code); code->module_fun = mp_parse_compile_execute(lex, parse_input_kind, NULL, NULL); return MP_OBJ_FROM_PTR(code); } diff --git a/py/builtinhelp.c b/py/builtinhelp.c index 86632f6dde139..c26a1a54908a5 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2013-2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/builtinimport.c b/py/builtinimport.c index 92f3150306d10..bf47b2567e8a4 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2013-2019 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * Copyright (c) 2021 Jim Mussared * @@ -31,7 +31,6 @@ #include #include "py/compile.h" -#include "py/gc_long_lived.h" #include "py/gc.h" #include "py/objmodule.h" #include "py/persistentcode.h" @@ -150,28 +149,28 @@ STATIC mp_import_stat_t stat_top_level_dir_or_file(qstr mod_name, vstr_t *dest) } #if MICROPY_MODULE_FROZEN_STR || MICROPY_ENABLE_COMPILER -STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex) { +STATIC void do_load_from_lexer(mp_module_context_t *context, mp_lexer_t *lex) { #if MICROPY_PY___FILE__ qstr source_name = lex->source_name; - mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); + mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif // parse, compile and execute the module in its context - mp_obj_dict_t *mod_globals = mp_obj_module_get_globals(module_obj); + mp_obj_dict_t *mod_globals = context->module.globals; mp_parse_compile_execute(lex, MP_PARSE_FILE_INPUT, mod_globals, mod_globals); - mp_obj_module_set_globals(module_obj, make_dict_long_lived(mod_globals, 10)); } #endif #if (MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD) || MICROPY_MODULE_FROZEN_MPY -STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code, const char *source_name) { +STATIC void do_execute_raw_code(mp_module_context_t *context, const mp_raw_code_t *rc, const mp_module_context_t *mc, const char *source_name) { (void)source_name; + #if MICROPY_PY___FILE__ - mp_store_attr(module_obj, MP_QSTR___file__, MP_OBJ_NEW_QSTR(qstr_from_str(source_name))); + mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(qstr_from_str(source_name))); #endif // execute the module in its context - mp_obj_dict_t *mod_globals = mp_obj_module_get_globals(module_obj); + mp_obj_dict_t *mod_globals = context->module.globals; // save context mp_obj_dict_t *volatile old_globals = mp_globals_get(); @@ -183,13 +182,11 @@ STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code, co nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - mp_obj_t module_fun = mp_make_function_from_raw_code(raw_code, MP_OBJ_NULL, MP_OBJ_NULL); + mp_obj_t module_fun = mp_make_function_from_raw_code(rc, mc, NULL); mp_call_function_0(module_fun); // finish nlr block, restore context nlr_pop(); - mp_obj_module_set_globals(module_obj, - make_dict_long_lived(mp_obj_module_get_globals(module_obj), 10)); mp_globals_set(old_globals); mp_locals_set(old_locals); } else { @@ -201,7 +198,7 @@ STATIC void do_execute_raw_code(mp_obj_t module_obj, mp_raw_code_t *raw_code, co } #endif -STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { +STATIC void do_load(mp_module_context_t *module_obj, vstr_t *file) { #if MICROPY_MODULE_FROZEN || MICROPY_ENABLE_COMPILER || (MICROPY_PERSISTENT_CODE_LOAD && MICROPY_HAS_FILE_READER) const char *file_str = vstr_null_terminated_str(file); #endif @@ -228,19 +225,22 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) { // its data) in the list of frozen files, execute it. #if MICROPY_MODULE_FROZEN_MPY if (frozen_type == MP_FROZEN_MPY) { - do_execute_raw_code(module_obj, modref, file_str + frozen_path_prefix_len); + const mp_frozen_module_t *frozen = modref; + module_obj->constants = frozen->constants; + do_execute_raw_code(module_obj, frozen->rc, module_obj, file_str + frozen_path_prefix_len); return; } #endif } + #endif // MICROPY_MODULE_FROZEN // If we support loading .mpy files then check if the file extension is of // the correct format and, if so, load and execute the file. #if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD if (file_str[file->len - 3] == 'm') { - mp_raw_code_t *raw_code = mp_raw_code_load_file(file_str); - do_execute_raw_code(module_obj, raw_code, file_str); + mp_compiled_module_t cm = mp_raw_code_load_file(file_str, module_obj); + do_execute_raw_code(module_obj, cm.rc, cm.context, file_str); return; } #endif @@ -376,6 +376,10 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, qstr umodule_name = qstr_from_str(umodule_buf); module_obj = mp_module_get_builtin(umodule_name); } + #elif MICROPY_PY_SYS + if (stat == MP_IMPORT_STAT_NO_EXIST && module_obj == MP_OBJ_NULL && level_mod_name == MP_QSTR_sys) { + module_obj = MP_OBJ_FROM_PTR(&mp_module_sys); + } #endif } else { DEBUG_printf("Searching for sub-module\n"); @@ -439,7 +443,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, size_t orig_path_len = path->len; vstr_add_str(path, PATH_SEP_CHAR "__init__.py"); if (stat_file_py_or_mpy(path) == MP_IMPORT_STAT_FILE) { - do_load(module_obj, path); + do_load(MP_OBJ_TO_PTR(module_obj), path); } else { // No-op. Nothing to load. // mp_warning("%s is imported as namespace package", vstr_str(&path)); @@ -448,7 +452,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, path->len = orig_path_len; } else { // MP_IMPORT_STAT_FILE // File -- execute "path.(m)py". - do_load(module_obj, path); + do_load(MP_OBJ_TO_PTR(module_obj), path); // Note: This should be the last component in the import path. If // there are remaining components then it's an ImportError // because the current path(the module that was just loaded) is @@ -456,6 +460,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, // because the file will not exist. } + // CIRCUITPY // Loading a module thrashes the heap significantly so we explicitly clean up // afterwards. gc_collect(); diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 2db1e0dcc833e..8186d24b2aba2 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -84,12 +84,6 @@ CFLAGS += -DCIRCUITPY_TRANSLATE_OBJECT=$(CIRCUITPY_TRANSLATE_OBJECT) ### # Handle frozen modules. -ifneq ($(FROZEN_DIR),) -# To use frozen source modules, put your .py files in a subdirectory (eg scripts/) -# and then invoke make with FROZEN_DIR=scripts (be sure to build from scratch). -CFLAGS += -DMICROPY_MODULE_FROZEN_STR -endif - # To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and # then invoke make with FROZEN_MPY_DIR=frozen or FROZEN_MPY_DIRS="dir1 dir2" # (be sure to build from scratch). @@ -714,7 +708,7 @@ SRC_MOD += $(addprefix lib/mp3/src/, \ subband.c \ trigtabs.c \ ) -$(BUILD)/lib/mp3/src/buffers.o: CFLAGS += -include "py/misc.h" -D'MPDEC_ALLOCATOR(x)=m_malloc(x,0)' -D'MPDEC_FREE(x)=m_free(x)' +$(BUILD)/lib/mp3/src/buffers.o: CFLAGS += -include "py/misc.h" -D'MPDEC_ALLOCATOR(x)=m_malloc(x)' -D'MPDEC_FREE(x)=m_free(x)' endif ifeq ($(CIRCUITPY_RGBMATRIX),1) SRC_MOD += $(addprefix lib/protomatter/src/, \ diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 7e858212a55e9..ab72eddd40d11 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -55,6 +55,16 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_BEGIN_ATOMIC_SECTION() (common_hal_mcu_disable_interrupts(), 0) #define MICROPY_END_ATOMIC_SECTION(state) ((void)state, common_hal_mcu_enable_interrupts()) +// MicroPython-only options not used by CircuitPython, but present in various files +// inherited from MicroPython, especially in extmod/ +#define MICROPY_ENABLE_DYNRUNTIME (0) +#define MICROPY_PY_BLUETOOTH (0) +#define MICROPY_PY_LWIP_SLIP (0) +#define MICROPY_PY_OS_DUPTERM (0) +#define MICROPY_ROM_TEXT_COMPRESSION (0) +#define MICROPY_VFS_LFS1 (0) +#define MICROPY_VFS_LFS2 (0) + // Sorted alphabetically for easy finding. // // default is 128; consider raising to reduce fragmentation. @@ -73,6 +83,7 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_ENABLE_DOC_STRING (0) #define MICROPY_ENABLE_FINALISER (1) #define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_PYSTACK (1) #define MICROPY_TRACKED_ALLOC (CIRCUITPY_SSL_MBEDTLS) #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_EPOCH_IS_1970 (1) @@ -96,7 +107,6 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_PY_ARRAY (CIRCUITPY_ARRAY) #define MICROPY_PY_ARRAY_SLICE_ASSIGN (1) #define MICROPY_PY_ATTRTUPLE (1) - #define MICROPY_PY_BUILTINS_BYTEARRAY (1) #define MICROPY_PY_BUILTINS_ENUMERATE (1) #define MICROPY_PY_BUILTINS_FILTER (1) @@ -144,7 +154,6 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_QSTR_BYTES_IN_HASH (1) #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_REPL_EVENT_DRIVEN (0) -#define MICROPY_ENABLE_PYSTACK (1) #define CIRCUITPY_SETTABLE_PYSTACK (1) #define MICROPY_STACK_CHECK (1) #define MICROPY_STREAMS_NON_BLOCK (1) @@ -205,7 +214,6 @@ typedef long mp_off_t; #define mp_type_fileio mp_type_vfs_fat_fileio #define mp_type_textio mp_type_vfs_fat_textio -#define mp_import_stat mp_vfs_import_stat #define mp_builtin_open_obj mp_vfs_open_obj @@ -483,13 +491,6 @@ void background_callback_run_all(void); #define CIRCUITPY_VERBOSE_BLE 0 -// This trades ~1k flash space (1) for that much in RAM plus the cost to compute -// the values once on init (0). Only turn it off, when you really need the flash -// space and are willing to trade the RAM. -#ifndef CIRCUITPY_PRECOMPUTE_QSTR_ATTR -#define CIRCUITPY_PRECOMPUTE_QSTR_ATTR (1) -#endif - // Display the Blinka logo in the REPL on displayio displays. #ifndef CIRCUITPY_REPL_LOGO #define CIRCUITPY_REPL_LOGO (1) diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 2f7bd580f647e..5ba3f8640b969 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -61,6 +61,9 @@ CFLAGS += -DCIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE=$(CIRCUITPY_OPTIMIZE_PROPERTY MICROPY_PY_ASYNC_AWAIT ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DMICROPY_PY_ASYNC_AWAIT=$(MICROPY_PY_ASYNC_AWAIT) +# unused by CIRCUITPYTHON +MICROPY_ROM_TEXT_COMPRESSION = 0 + # uasyncio # By default, include uasyncio if async/await are available. MICROPY_PY_UASYNCIO ?= $(MICROPY_PY_ASYNC_AWAIT) @@ -624,6 +627,6 @@ $(BUILD)/frozen_mpy: $(FROZEN_MPY_DIRS) $(BUILD)/manifest.py: $(BUILD)/frozen_mpy | $(TOP)/py/circuitpy_mpconfig.mk mpconfigport.mk boards/$(BOARD)/mpconfigboard.mk $(ECHO) MKMANIFEST $(FROZEN_MPY_DIRS) - (cd $(BUILD)/frozen_mpy && find * -name \*.py -exec printf 'freeze_as_mpy("frozen_mpy", "%s")\n' {} \; )> $@.tmp && mv -f $@.tmp $@ + $(Q)(cd $(BUILD)/frozen_mpy && find * -name \*.py -exec printf 'freeze_as_mpy("frozen_mpy", "%s")\n' {} \; )> $@.tmp && mv -f $@.tmp $@ FROZEN_MANIFEST=$(BUILD)/manifest.py endif diff --git a/py/compile.c b/py/compile.c index 3668bee320ca7..82ab354eb4996 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2020 Damien P. George + * Copyright (c) 2013-2020 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -35,7 +35,9 @@ #include "py/compile.h" #include "py/runtime.h" #include "py/asmbase.h" +#include "py/nativeglue.h" #include "py/persistentcode.h" +#include "py/smallint.h" #include "supervisor/shared/translate/translate.h" @@ -90,7 +92,7 @@ typedef enum { #if MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER #define NATIVE_EMITTER(f) emit_native_table[mp_dynamic_compiler.native_arch]->emit_##f -#define NATIVE_EMITTER_TABLE emit_native_table[mp_dynamic_compiler.native_arch] +#define NATIVE_EMITTER_TABLE (emit_native_table[mp_dynamic_compiler.native_arch]) STATIC const emit_method_table_t *emit_native_table[] = { NULL, @@ -123,7 +125,7 @@ STATIC const emit_method_table_t *emit_native_table[] = { #else #error "unknown native emitter" #endif -#define NATIVE_EMITTER_TABLE &NATIVE_EMITTER(method_table) +#define NATIVE_EMITTER_TABLE (&NATIVE_EMITTER(method_table)) #endif #if MICROPY_EMIT_INLINE_ASM && MICROPY_DYNAMIC_COMPILER @@ -164,8 +166,6 @@ STATIC const emit_inline_asm_method_table_t *emit_asm_table[] = { // elements in this struct are ordered to make it compact typedef struct _compiler_t { - qstr source_file; - uint8_t is_repl; uint8_t pass; // holds enum type pass_kind_t uint8_t have_star; @@ -196,8 +196,60 @@ typedef struct _compiler_t { emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm #endif + + mp_emit_common_t emit_common; } compiler_t; +/******************************************************************************/ +// mp_emit_common_t helper functions +// These are defined here so they can be inlined, to reduce code size. + +STATIC void mp_emit_common_init(mp_emit_common_t *emit, qstr source_file) { + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + mp_map_init(&emit->qstr_map, 1); + + // add the source file as the first entry in the qstr table + mp_map_elem_t *elem = mp_map_lookup(&emit->qstr_map, MP_OBJ_NEW_QSTR(source_file), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); + elem->value = MP_OBJ_NEW_SMALL_INT(0); + #endif + mp_obj_list_init(&emit->const_obj_list, 0); +} + +STATIC void mp_emit_common_start_pass(mp_emit_common_t *emit, pass_kind_t pass) { + emit->pass = pass; + if (pass == MP_PASS_CODE_SIZE) { + if (emit->ct_cur_child == 0) { + emit->children = NULL; + } else { + emit->children = m_new0(mp_raw_code_t *, emit->ct_cur_child); + } + } + emit->ct_cur_child = 0; +} + +STATIC void mp_emit_common_populate_module_context(mp_emit_common_t *emit, qstr source_file, mp_module_context_t *context) { + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + size_t qstr_map_used = emit->qstr_map.used; + mp_module_context_alloc_tables(context, qstr_map_used, emit->const_obj_list.len); + for (size_t i = 0; i < emit->qstr_map.alloc; ++i) { + if (mp_map_slot_is_filled(&emit->qstr_map, i)) { + size_t idx = MP_OBJ_SMALL_INT_VALUE(emit->qstr_map.table[i].value); + qstr qst = MP_OBJ_QSTR_VALUE(emit->qstr_map.table[i].key); + context->constants.qstr_table[idx] = qst; + } + } + #else + mp_module_context_alloc_tables(context, 0, emit->const_obj_list.len); + context->constants.source_file = source_file; + #endif + + for (size_t i = 0; i < emit->const_obj_list.len; ++i) { + context->constants.obj_table[i] = emit->const_obj_list.items[i]; + } +} + +/******************************************************************************/ + STATIC void compile_error_set_line(compiler_t *comp, mp_parse_node_t pn) { // if the line of the error is unknown then try to update it from the pn if (comp->compile_error_line == 0 && MP_PARSE_NODE_IS_STRUCT(pn)) { @@ -248,7 +300,7 @@ STATIC void compile_decrease_except_level(compiler_t *comp) { } STATIC scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) { - scope_t *scope = scope_new(kind, pn, comp->source_file, emit_options); + scope_t *scope = scope_new(kind, pn, emit_options); scope->parent = comp->scope_cur; scope->next = NULL; if (comp->scope_head == NULL) { @@ -802,6 +854,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, size_t name_len, mp_par *emit_options = MP_EMIT_OPT_BYTECODE; // @micropython.native decorator. } else if (attr == MP_QSTR_native) { + // CIRCUITPY // Different from MicroPython: native doesn't raise SyntaxError if native support isn't // compiled, it just passes through the function unmodified. #if MICROPY_EMIT_NATIVE @@ -829,7 +882,7 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, size_t name_len, mp_par compile_syntax_error(comp, name_nodes[1], MP_ERROR_TEXT("invalid micropython decorator")); } - #if MICROPY_DYNAMIC_COMPILER + #if MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER if (*emit_options == MP_EMIT_OPT_NATIVE_PYTHON || *emit_options == MP_EMIT_OPT_VIPER) { if (emit_native_table[mp_dynamic_compiler.native_arch] == NULL) { compile_syntax_error(comp, name_nodes[1], MP_ERROR_TEXT("invalid architecture")); @@ -1076,14 +1129,19 @@ STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) { if (!is_as) { *q_base = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); } - int n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); - int len = n - 1; - for (int i = 0; i < n; i++) { + size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); + if (n == 0) { + // There must be at least one node in this PN_dotted_name. + // Let the compiler know this so it doesn't warn, and can generate better code. + MP_UNREACHABLE; + } + size_t len = n - 1; + for (size_t i = 0; i < n; i++) { len += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i])); } char *q_ptr = mp_local_alloc(len); char *str_dest = q_ptr; - for (int i = 0; i < n; i++) { + for (size_t i = 0; i < n; i++) { if (i > 0) { *str_dest++ = '.'; } @@ -1096,7 +1154,7 @@ STATIC void do_import_name(compiler_t *comp, mp_parse_node_t pn, qstr *q_base) { mp_local_free(q_ptr); EMIT_ARG(import, q_full, MP_EMIT_IMPORT_NAME); if (is_as) { - for (int i = 1; i < n; i++) { + for (size_t i = 1; i < n; i++) { EMIT_ARG(attr, MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]), MP_EMIT_ATTR_LOAD); } } @@ -2337,24 +2395,36 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar int n_positional = n_positional_extra; uint n_keyword = 0; uint star_flags = 0; - mp_parse_node_struct_t *star_args_node = NULL, *dblstar_args_node = NULL; + mp_uint_t star_args = 0; for (size_t i = 0; i < n_args; i++) { if (MP_PARSE_NODE_IS_STRUCT(args[i])) { mp_parse_node_struct_t *pns_arg = (mp_parse_node_struct_t *)args[i]; if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_star) { - if (star_flags & MP_EMIT_STAR_FLAG_SINGLE) { - compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("can't have multiple *x")); + if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) { + compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("* arg after **")); return; } - star_flags |= MP_EMIT_STAR_FLAG_SINGLE; - star_args_node = pns_arg; - } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) { - if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) { - compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("can't have multiple **x")); + #if MICROPY_DYNAMIC_COMPILER + if (i >= (size_t)mp_dynamic_compiler.small_int_bits - 1) + #else + if (i >= MP_SMALL_INT_BITS - 1) + #endif + { + // If there are not enough bits in a small int to fit the flag, then we consider + // it a syntax error. It should be unlikely to have this many args in practice. + compile_syntax_error(comp, (mp_parse_node_t)pns_arg, MP_ERROR_TEXT("too many args")); return; } + star_flags |= MP_EMIT_STAR_FLAG_SINGLE; + star_args |= (mp_uint_t)1 << i; + compile_node(comp, pns_arg->nodes[0]); + n_positional++; + } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_arglist_dbl_star) { star_flags |= MP_EMIT_STAR_FLAG_DOUBLE; - dblstar_args_node = pns_arg; + // double-star args are stored as kw arg with key of None + EMIT(load_null); + compile_node(comp, pns_arg->nodes[0]); + n_keyword++; } else if (MP_PARSE_NODE_STRUCT_KIND(pns_arg) == PN_argument) { #if MICROPY_PY_ASSIGN_EXPR if (MP_PARSE_NODE_IS_STRUCT_KIND(pns_arg->nodes[1], PN_argument_3)) { @@ -2369,7 +2439,7 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar } EMIT_ARG(load_const_str, MP_PARSE_NODE_LEAF_ARG(pns_arg->nodes[0])); compile_node(comp, pns_arg->nodes[1]); - n_keyword += 1; + n_keyword++; } else { compile_comprehension(comp, pns_arg, SCOPE_GEN_EXPR); n_positional++; @@ -2379,12 +2449,12 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar } } else { normal_argument: - if (star_flags) { - compile_syntax_error(comp, args[i], MP_ERROR_TEXT("non-keyword arg after */**")); + if (star_flags & MP_EMIT_STAR_FLAG_DOUBLE) { + compile_syntax_error(comp, args[i], MP_ERROR_TEXT("positional arg after **")); return; } if (n_keyword > 0) { - compile_syntax_error(comp, args[i], MP_ERROR_TEXT("non-keyword arg after keyword arg")); + compile_syntax_error(comp, args[i], MP_ERROR_TEXT("positional arg after keyword arg")); return; } compile_node(comp, args[i]); @@ -2392,19 +2462,9 @@ STATIC void compile_trailer_paren_helper(compiler_t *comp, mp_parse_node_t pn_ar } } - // compile the star/double-star arguments if we had them - // if we had one but not the other then we load "null" as a place holder if (star_flags != 0) { - if (star_args_node == NULL) { - EMIT(load_null); - } else { - compile_node(comp, star_args_node->nodes[0]); - } - if (dblstar_args_node == NULL) { - EMIT(load_null); - } else { - compile_node(comp, dblstar_args_node->nodes[0]); - } + // one extra object that contains the star_args map + EMIT_ARG(load_const_small_int, star_args); } // emit the function/method call @@ -2714,12 +2774,7 @@ STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pn #endif STATIC mp_obj_t get_const_object(mp_parse_node_struct_t *pns) { - #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D - // nodes are 32-bit pointers, but need to extract 64-bit object - return (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32); - #else - return (mp_obj_t)pns->nodes[0]; - #endif + return mp_parse_node_extract_const_object(pns); } STATIC void compile_const_object(compiler_t *comp, mp_parse_node_struct_t *pns) { @@ -2744,23 +2799,7 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) { // pass } else if (MP_PARSE_NODE_IS_SMALL_INT(pn)) { mp_int_t arg = MP_PARSE_NODE_LEAF_SMALL_INT(pn); - #if MICROPY_DYNAMIC_COMPILER - mp_uint_t sign_mask = -((mp_uint_t)1 << (mp_dynamic_compiler.small_int_bits - 1)); - if ((arg & sign_mask) == 0 || (arg & sign_mask) == sign_mask) { - // integer fits in target runtime's small-int - EMIT_ARG(load_const_small_int, arg); - } else { - // integer doesn't fit, so create a multi-precision int object - // (but only create the actual object on the last pass) - if (comp->pass != MP_PASS_EMIT) { - EMIT_ARG(load_const_obj, mp_const_none); - } else { - EMIT_ARG(load_const_obj, mp_obj_new_int_from_ll(arg)); - } - } - #else EMIT_ARG(load_const_small_int, arg); - #endif } else if (MP_PARSE_NODE_IS_LEAF(pn)) { uintptr_t arg = MP_PARSE_NODE_LEAF_ARG(pn); switch (MP_PARSE_NODE_LEAF_KIND(pn)) { @@ -2770,16 +2809,6 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) { case MP_PARSE_NODE_STRING: EMIT_ARG(load_const_str, arg); break; - case MP_PARSE_NODE_BYTES: - // only create and load the actual bytes object on the last pass - if (comp->pass != MP_PASS_EMIT) { - EMIT_ARG(load_const_obj, mp_const_none); - } else { - size_t len; - const byte *data = qstr_data(arg, &len); - EMIT_ARG(load_const_obj, mp_obj_new_bytes(data, len)); - } - break; case MP_PARSE_NODE_TOKEN: default: if (arg == MP_TOKEN_NEWLINE) { @@ -2998,10 +3027,11 @@ STATIC void check_for_doc_string(compiler_t *comp, mp_parse_node_t pn) { #endif } -STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { +STATIC bool compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { comp->pass = pass; comp->scope_cur = scope; comp->next_label = 0; + mp_emit_common_start_pass(&comp->emit_common, pass); EMIT_ARG(start_pass, pass, scope); reserve_labels_for_native(comp, 6); // used by native's start_pass @@ -3155,10 +3185,12 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { EMIT(return_value); } - EMIT(end_pass); + bool pass_complete = EMIT(end_pass); // make sure we match all the exception levels assert(comp->cur_except_level == 0); + + return pass_complete; } #if MICROPY_EMIT_INLINE_ASM @@ -3322,9 +3354,10 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind f, mp_asm_base_get_code_size((mp_asm_base_t *)comp->emit_inline_asm), NULL, #if MICROPY_PERSISTENT_CODE_SAVE - 0, 0, 0, 0, NULL, + 0, + 0, #endif - comp->scope_cur->num_pos_args, 0, type_sig); + 0, comp->scope_cur->num_pos_args, type_sig); } } @@ -3432,15 +3465,15 @@ STATIC void scope_compute_things(scope_t *scope) { #if !MICROPY_PERSISTENT_CODE_SAVE STATIC #endif -mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) { +mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *context) { // put compiler state on the stack, it's relatively small compiler_t comp_state = {0}; compiler_t *comp = &comp_state; - comp->source_file = source_file; comp->is_repl = is_repl; comp->break_label = INVALID_LABEL; comp->continue_label = INVALID_LABEL; + mp_emit_common_init(&comp->emit_common, source_file); // create the module scope #if MICROPY_EMIT_NATIVE @@ -3451,9 +3484,9 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f scope_t *module_scope = scope_new_and_link(comp, SCOPE_MODULE, parse_tree->root, emit_opt); // create standard emitter; it's used at least for MP_PASS_SCOPE - emit_t *emit_bc = emit_bc_new(); + emit_t *emit_bc = emit_bc_new(&comp->emit_common); - // compile pass 1 + // compile MP_PASS_SCOPE comp->emit = emit_bc; #if MICROPY_EMIT_NATIVE comp->emit_method_table = &emit_bc_method_table; @@ -3491,7 +3524,7 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f // set max number of labels now that it's calculated emit_bc_set_max_num_labels(emit_bc, max_num_labels); - // compile pass 2 and 3 + // compile MP_PASS_STACK_SIZE, MP_PASS_CODE_SIZE, MP_PASS_EMIT #if MICROPY_EMIT_NATIVE emit_t *emit_native = NULL; #endif @@ -3531,7 +3564,7 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f case MP_EMIT_OPT_NATIVE_PYTHON: case MP_EMIT_OPT_VIPER: if (emit_native == NULL) { - emit_native = NATIVE_EMITTER(new)(&comp->compile_error, &comp->next_label, max_num_labels); + emit_native = NATIVE_EMITTER(new)(&comp->emit_common, &comp->compile_error, &comp->next_label, max_num_labels); } comp->emit_method_table = NATIVE_EMITTER_TABLE; comp->emit = emit_native; @@ -3555,8 +3588,10 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f } // final pass: emit code + // the emitter can request multiple of these passes if (comp->compile_error == MP_OBJ_NULL) { - compile_scope(comp, s, MP_PASS_EMIT); + while (!compile_scope(comp, s, MP_PASS_EMIT)) { + } } } } @@ -3566,10 +3601,45 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f // number for the start of this scope compile_error_set_line(comp, comp->scope_cur->pn); // add a traceback to the exception using relevant source info - mp_obj_exception_add_traceback(comp->compile_error, comp->source_file, + mp_obj_exception_add_traceback(comp->compile_error, source_file, comp->compile_error_line, comp->scope_cur->simple_name); } + // construct the global qstr/const table for this module + mp_compiled_module_t cm; + cm.rc = module_scope->raw_code; + cm.context = context; + #if MICROPY_PERSISTENT_CODE_SAVE + cm.has_native = false; + #if MICROPY_EMIT_NATIVE + if (emit_native != NULL) { + cm.has_native = true; + } + #endif + #if MICROPY_EMIT_INLINE_ASM + if (comp->emit_inline_asm != NULL) { + cm.has_native = true; + } + #endif + cm.n_qstr = comp->emit_common.qstr_map.used; + cm.n_obj = comp->emit_common.const_obj_list.len; + #endif + if (comp->compile_error == MP_OBJ_NULL) { + mp_emit_common_populate_module_context(&comp->emit_common, source_file, context); + + #if MICROPY_DEBUG_PRINTERS + // now that the module context is valid, the raw codes can be printed + if (mp_verbose_flag >= 2) { + for (scope_t *s = comp->scope_head; s != NULL; s = s->next) { + mp_raw_code_t *rc = s->raw_code; + if (rc->kind == MP_CODE_BYTECODE) { + mp_bytecode_print(&mp_plat_print, rc, &cm.context->constants); + } + } + } + #endif + } + // free the emitters emit_bc_free(emit_bc); @@ -3588,7 +3658,6 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f mp_parse_tree_clear(parse_tree); // free the scopes - mp_raw_code_t *outer_raw_code = module_scope->raw_code; for (scope_t *s = module_scope; s;) { scope_t *next = s->next; scope_free(s); @@ -3597,15 +3666,17 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f if (comp->compile_error != MP_OBJ_NULL) { nlr_raise(comp->compile_error); - } else { - return outer_raw_code; } + + return cm; } mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) { - mp_raw_code_t *rc = mp_compile_to_raw_code(parse_tree, source_file, is_repl); + mp_module_context_t *context = m_new_obj(mp_module_context_t); + context->module.globals = mp_globals_get(); + mp_compiled_module_t cm = mp_compile_to_raw_code(parse_tree, source_file, is_repl, context); // return function that executes the outer module - return mp_make_function_from_raw_code(rc, MP_OBJ_NULL, MP_OBJ_NULL); + return mp_make_function_from_raw_code(cm.rc, cm.context, NULL); } #endif // MICROPY_ENABLE_COMPILER diff --git a/py/compile.h b/py/compile.h index 348beff15fa2f..ae87bf2a04cba 100644 --- a/py/compile.h +++ b/py/compile.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,11 +32,12 @@ // the compiler will raise an exception if an error occurred // the compiler will clear the parse tree before it returns +// mp_globals_get() will be used for the context mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl); #if MICROPY_PERSISTENT_CODE_SAVE // this has the same semantics as mp_compile -mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl); +mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *globals); #endif // this is implemented in runtime.c diff --git a/py/dynruntime.h b/py/dynruntime.h index 608cdec0971c2..b7a9a89156457 100644 --- a/py/dynruntime.h +++ b/py/dynruntime.h @@ -30,6 +30,7 @@ // MicroPython runtime API defined in py/obj.h and py/runtime.h. #include "py/nativeglue.h" +#include "py/objfun.h" #include "py/objstr.h" #include "py/objtype.h" @@ -43,13 +44,14 @@ #undef mp_const_none #undef mp_const_false #undef mp_const_true +#undef mp_const_empty_bytes #undef mp_const_empty_tuple #undef nlr_raise /******************************************************************************/ // Memory allocation -#define m_malloc(n,_) (m_malloc_dyn((n))) +#define m_malloc(n) (m_malloc_dyn((n))) #define m_free(ptr) (m_free_dyn((ptr))) #define m_realloc(ptr, new_num_bytes) (m_realloc_dyn((ptr), (new_num_bytes))) @@ -80,7 +82,11 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define MP_OBJ_NEW_QSTR(x) MP_OBJ_NEW_QSTR_##x #define mp_type_type (*mp_fun_table.type_type) +#define mp_type_NoneType (*mp_obj_get_type(mp_const_none)) +#define mp_type_bool (*mp_obj_get_type(mp_const_false)) +#define mp_type_int (*(mp_obj_type_t *)(mp_load_global(MP_QSTR_int))) #define mp_type_str (*mp_fun_table.type_str) +#define mp_type_bytes (*(mp_obj_type_t *)(mp_load_global(MP_QSTR_bytes))) #define mp_type_tuple (*((mp_obj_base_t *)mp_const_empty_tuple)->type) #define mp_type_list (*mp_fun_table.type_list) #define mp_type_EOFError (*(mp_obj_type_t *)(mp_load_global(MP_QSTR_EOFError))) @@ -99,6 +105,7 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define mp_const_none ((mp_obj_t)mp_fun_table.const_none) #define mp_const_false ((mp_obj_t)mp_fun_table.const_false) #define mp_const_true ((mp_obj_t)mp_fun_table.const_true) +#define mp_const_empty_bytes (mp_type_bytes.make_new(NULL, 0, 0, NULL)) #define mp_const_empty_tuple (mp_fun_table.new_tuple(0, NULL)) #define mp_obj_new_bool(b) ((b) ? (mp_obj_t)mp_fun_table.const_true : (mp_obj_t)mp_fun_table.const_false) @@ -110,6 +117,7 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define mp_obj_new_bytearray_by_ref(n, i) (mp_fun_table.obj_new_bytearray_by_ref((n), (i))) #define mp_obj_new_tuple(n, items) (mp_fun_table.new_tuple((n), (items))) #define mp_obj_new_list(n, items) (mp_fun_table.new_list((n), (items))) +#define mp_obj_new_dict(n) (mp_fun_table.new_dict((n))) #define mp_obj_get_type(o) (mp_fun_table.obj_get_type((o))) #define mp_obj_cast_to_native_base(o, t) (mp_obj_cast_to_native_base_dyn((o), (t))) @@ -124,6 +132,9 @@ static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { #define mp_obj_subscr(base, index, val) (mp_fun_table.obj_subscr((base), (index), (val))) #define mp_obj_get_array(o, len, items) (mp_obj_get_array_dyn((o), (len), (items))) #define mp_obj_list_append(list, item) (mp_fun_table.list_append((list), (item))) +#define mp_obj_dict_store(dict, key, val) (mp_fun_table.dict_store((dict), (key), (val))) + +#define mp_obj_malloc_helper(n, t) (mp_obj_malloc_helper_dyn(n, t)) #define mp_obj_assert_native_inited(o) (mp_fun_table.assert_native_inited((o))) @@ -140,8 +151,7 @@ static inline mp_obj_t mp_obj_cast_to_native_base_dyn(mp_obj_t self_in, mp_const if (MP_OBJ_FROM_PTR(self_type) == native_type) { return self_in; - } - if (self_type->parent != native_type) { + } else if (self_type->parent != native_type) { // The self_in object is not a direct descendant of native_type, so fail the cast. // This is a very simple version of mp_obj_is_subclass_fast that could be improved. return MP_OBJ_NULL; @@ -165,6 +175,11 @@ static inline mp_obj_t mp_obj_len_dyn(mp_obj_t o) { return mp_fun_table.call_function_n_kw(mp_fun_table.load_name(MP_QSTR_len), 1, &o); } +static inline void *mp_obj_malloc_helper_dyn(size_t num_bytes, const mp_obj_type_t *type) { + mp_obj_base_t *base = (mp_obj_base_t *)m_malloc(num_bytes); + base->type = type; + return base; +} /******************************************************************************/ // General runtime functions @@ -181,8 +196,8 @@ static inline mp_obj_t mp_obj_len_dyn(mp_obj_t o) { #define mp_unary_op(op, obj) (mp_fun_table.unary_op((op), (obj))) #define mp_binary_op(op, lhs, rhs) (mp_fun_table.binary_op((op), (lhs), (rhs))) -#define mp_make_function_from_raw_code(rc, def_args, def_kw_args) \ - (mp_fun_table.make_function_from_raw_code((rc), (def_args), (def_kw_args))) +#define mp_make_function_from_raw_code(rc, context, def_args) \ + (mp_fun_table.make_function_from_raw_code((rc), (context), (def_args))) #define mp_call_function_n_kw(fun, n_args, n_kw, args) \ (mp_fun_table.call_function_n_kw((fun), (n_args) | ((n_kw) << 8), args)) @@ -191,11 +206,10 @@ static inline mp_obj_t mp_obj_len_dyn(mp_obj_t o) { (mp_fun_table.arg_check_num_sig((n_args), (n_kw), MP_OBJ_FUN_MAKE_SIG((n_args_min), (n_args_max), (takes_kw)))) #define MP_DYNRUNTIME_INIT_ENTRY \ - mp_obj_t old_globals = mp_fun_table.swap_globals(self->globals); \ + mp_obj_t old_globals = mp_fun_table.swap_globals(self->context->module.globals); \ mp_raw_code_t rc; \ rc.kind = MP_CODE_NATIVE_VIPER; \ rc.scope_flags = 0; \ - rc.const_table = (void *)self->const_table; \ (void)rc; #define MP_DYNRUNTIME_INIT_EXIT \ diff --git a/py/dynruntime.mk b/py/dynruntime.mk index db06d41e73767..09cbb2dd37cbb 100644 --- a/py/dynruntime.mk +++ b/py/dynruntime.mk @@ -55,6 +55,13 @@ CROSS = CFLAGS += -fno-stack-protector MICROPY_FLOAT_IMPL ?= double +else ifeq ($(ARCH),armv6m) + +# thumb +CROSS = arm-none-eabi- +CFLAGS += -mthumb -mcpu=cortex-m0 +MICROPY_FLOAT_IMPL ?= none + else ifeq ($(ARCH),armv7m) # thumb diff --git a/py/emit.h b/py/emit.h index 2797fb84ea697..608734552af49 100644 --- a/py/emit.h +++ b/py/emit.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -43,7 +43,7 @@ typedef enum { MP_PASS_SCOPE = 1, // work out id's and their kind, and number of labels MP_PASS_STACK_SIZE = 2, // work out maximum stack size MP_PASS_CODE_SIZE = 3, // work out code size and label offsets - MP_PASS_EMIT = 4, // emit code + MP_PASS_EMIT = 4, // emit code (may be run multiple times if the emitter requests it) } pass_kind_t; #define MP_EMIT_STAR_FLAG_SINGLE (0x01) @@ -92,6 +92,16 @@ typedef enum { typedef struct _emit_t emit_t; +typedef struct _mp_emit_common_t { + pass_kind_t pass; + uint16_t ct_cur_child; + mp_raw_code_t **children; + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + mp_map_t qstr_map; + #endif + mp_obj_list_t const_obj_list; +} mp_emit_common_t; + typedef struct _mp_emit_method_table_id_ops_t { void (*local)(emit_t *emit, qstr qst, mp_uint_t local_num, int kind); void (*global)(emit_t *emit, qstr qst, int kind); @@ -99,12 +109,12 @@ typedef struct _mp_emit_method_table_id_ops_t { typedef struct _emit_method_table_t { #if MICROPY_DYNAMIC_COMPILER - emit_t *(*emit_new)(mp_obj_t * error_slot, uint *label_slot, mp_uint_t max_num_labels); + emit_t *(*emit_new)(mp_emit_common_t * emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); void (*emit_free)(emit_t *emit); #endif void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope); - void (*end_pass)(emit_t *emit); + bool (*end_pass)(emit_t *emit); bool (*last_emit_was_return_value)(emit_t *emit); void (*adjust_stack_size)(emit_t *emit, mp_int_t delta); void (*set_source_line)(emit_t *emit, mp_uint_t line); @@ -161,6 +171,23 @@ typedef struct _emit_method_table_t { void (*end_except_handler)(emit_t *emit); } emit_method_table_t; +#if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE +qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst); +#else +static inline qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst) { + return qst; +} +#endif + +size_t mp_emit_common_use_const_obj(mp_emit_common_t *emit, mp_obj_t const_obj); + +static inline size_t mp_emit_common_alloc_const_child(mp_emit_common_t *emit, mp_raw_code_t *rc) { + if (emit->pass == MP_PASS_EMIT) { + emit->children[emit->ct_cur_child] = rc; + } + return emit->ct_cur_child++; +} + static inline void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst) { scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT); } @@ -180,13 +207,13 @@ extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops; extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops; extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops; -emit_t *emit_bc_new(void); -emit_t *emit_native_x64_new(mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); -emit_t *emit_native_x86_new(mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); -emit_t *emit_native_thumb_new(mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); -emit_t *emit_native_arm_new(mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); -emit_t *emit_native_xtensa_new(mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); -emit_t *emit_native_xtensawin_new(mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_bc_new(mp_emit_common_t *emit_common); +emit_t *emit_native_x64_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_native_x86_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_native_thumb_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_native_arm_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_native_xtensa_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_native_xtensawin_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels); @@ -199,7 +226,7 @@ void emit_native_xtensa_free(emit_t *emit); void emit_native_xtensawin_free(emit_t *emit); void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope); -void mp_emit_bc_end_pass(emit_t *emit); +bool mp_emit_bc_end_pass(emit_t *emit); bool mp_emit_bc_last_emit_was_return_value(emit_t *emit); void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta); void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t line); diff --git a/py/emitbc.c b/py/emitbc.c index 80d0bf489bfb8..2007975c5e9b5 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2013-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,16 +28,17 @@ #include #include #include +#include #include #include "py/mpstate.h" +#include "py/smallint.h" #include "py/emit.h" #include "py/bc0.h" #if MICROPY_ENABLE_COMPILER -#define BYTES_FOR_INT ((MP_BYTES_PER_OBJ_WORD * 8 + 6) / 7) -#define DUMMY_DATA_SIZE (BYTES_FOR_INT) +#define DUMMY_DATA_SIZE (MP_ENCODE_UINT_MAX_BYTES) struct _emit_t { // Accessed as mp_obj_t, so must be aligned as such, and we rely on the @@ -50,66 +51,45 @@ struct _emit_t { int stack_size; + mp_emit_common_t *emit_common; scope_t *scope; mp_uint_t last_source_line_offset; mp_uint_t last_source_line; - mp_uint_t max_num_labels; - mp_uint_t *label_offsets; + size_t max_num_labels; + size_t *label_offsets; size_t code_info_offset; size_t code_info_size; size_t bytecode_offset; size_t bytecode_size; byte *code_base; // stores both byte code and code info + bool overflow; size_t n_info; size_t n_cell; - - #if MICROPY_PERSISTENT_CODE - uint16_t ct_cur_obj; - uint16_t ct_num_obj; - uint16_t ct_cur_raw_code; - #endif - mp_uint_t *const_table; }; -emit_t *emit_bc_new(void) { +emit_t *emit_bc_new(mp_emit_common_t *emit_common) { emit_t *emit = m_new0(emit_t, 1); + emit->emit_common = emit_common; return emit; } void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels) { emit->max_num_labels = max_num_labels; - emit->label_offsets = m_new(mp_uint_t, emit->max_num_labels); + emit->label_offsets = m_new(size_t, emit->max_num_labels); } void emit_bc_free(emit_t *emit) { - m_del(mp_uint_t, emit->label_offsets, emit->max_num_labels); + m_del(size_t, emit->label_offsets, emit->max_num_labels); m_del_obj(emit_t, emit); } -typedef byte *(*emit_allocator_t)(emit_t *emit, int nbytes); - -STATIC void emit_write_uint(emit_t *emit, emit_allocator_t allocator, mp_uint_t val) { - // We store each 7 bits in a separate byte, and that's how many bytes needed - byte buf[BYTES_FOR_INT]; - byte *p = buf + sizeof(buf); - // We encode in little-ending order, but store in big-endian, to help decoding - do { - *--p = val & 0x7f; - val >>= 7; - } while (val != 0); - byte *c = allocator(emit, buf + sizeof(buf) - p); - while (p != buf + sizeof(buf) - 1) { - *c++ = *p++ | 0x80; - } - *c = *p; -} - // all functions must go through this one to emit code info -STATIC byte *emit_get_cur_to_write_code_info(emit_t *emit, int num_bytes_to_write) { +STATIC uint8_t *emit_get_cur_to_write_code_info(void *emit_in, size_t num_bytes_to_write) { + emit_t *emit = emit_in; if (emit->pass < MP_PASS_EMIT) { emit->code_info_offset += num_bytes_to_write; return emit->dummy_data; @@ -126,14 +106,7 @@ STATIC void emit_write_code_info_byte(emit_t *emit, byte val) { } STATIC void emit_write_code_info_qstr(emit_t *emit, qstr qst) { - #if MICROPY_PERSISTENT_CODE - assert((qst >> 16) == 0); - byte *c = emit_get_cur_to_write_code_info(emit, 2); - c[0] = qst; - c[1] = qst >> 8; - #else - emit_write_uint(emit, emit_get_cur_to_write_code_info, qst); - #endif + mp_encode_uint(emit, emit_get_cur_to_write_code_info, mp_emit_common_use_qstr(emit->emit_common, qst)); } #if MICROPY_ENABLE_SOURCE_LINE @@ -166,7 +139,8 @@ STATIC void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_sk #endif // all functions must go through this one to emit byte code -STATIC byte *emit_get_cur_to_write_bytecode(emit_t *emit, int num_bytes_to_write) { +STATIC uint8_t *emit_get_cur_to_write_bytecode(void *emit_in, size_t num_bytes_to_write) { + emit_t *emit = emit_in; if (emit->pass < MP_PASS_EMIT) { emit->bytecode_offset += num_bytes_to_write; return emit->dummy_data; @@ -189,12 +163,12 @@ STATIC void emit_write_bytecode_byte(emit_t *emit, int stack_adj, byte b1) { c[0] = b1; } -// Similar to emit_write_bytecode_uint(), just some extra handling to encode sign +// Similar to mp_encode_uint(), just some extra handling to encode sign STATIC void emit_write_bytecode_byte_int(emit_t *emit, int stack_adj, byte b1, mp_int_t num) { emit_write_bytecode_byte(emit, stack_adj, b1); // We store each 7 bits in a separate byte, and that's how many bytes needed - byte buf[BYTES_FOR_INT]; + byte buf[MP_ENCODE_UINT_MAX_BYTES]; byte *p = buf + sizeof(buf); // We encode in little-ending order, but store in big-endian, to help decoding do { @@ -218,94 +192,81 @@ STATIC void emit_write_bytecode_byte_int(emit_t *emit, int stack_adj, byte b1, m STATIC void emit_write_bytecode_byte_uint(emit_t *emit, int stack_adj, byte b, mp_uint_t val) { emit_write_bytecode_byte(emit, stack_adj, b); - emit_write_uint(emit, emit_get_cur_to_write_bytecode, val); + mp_encode_uint(emit, emit_get_cur_to_write_bytecode, val); } -#if MICROPY_PERSISTENT_CODE -STATIC void emit_write_bytecode_byte_const(emit_t *emit, int stack_adj, byte b, mp_uint_t n, mp_uint_t c) { - if (emit->pass == MP_PASS_EMIT) { - emit->const_table[n] = c; - } +STATIC void emit_write_bytecode_byte_const(emit_t *emit, int stack_adj, byte b, mp_uint_t n) { emit_write_bytecode_byte_uint(emit, stack_adj, b, n); } -#endif STATIC void emit_write_bytecode_byte_qstr(emit_t *emit, int stack_adj, byte b, qstr qst) { - #if MICROPY_PERSISTENT_CODE - assert((qst >> 16) == 0); - mp_emit_bc_adjust_stack_size(emit, stack_adj); - byte *c = emit_get_cur_to_write_bytecode(emit, 3); - c[0] = b; - c[1] = qst; - c[2] = qst >> 8; - #else - emit_write_bytecode_byte_uint(emit, stack_adj, b, qst); - #endif + emit_write_bytecode_byte_uint(emit, stack_adj, b, mp_emit_common_use_qstr(emit->emit_common, qst)); } STATIC void emit_write_bytecode_byte_obj(emit_t *emit, int stack_adj, byte b, mp_obj_t obj) { - #if MICROPY_PERSISTENT_CODE - emit_write_bytecode_byte_const(emit, stack_adj, b, - emit->scope->num_pos_args + emit->scope->num_kwonly_args - + emit->ct_cur_obj++, (mp_uint_t)obj); - #else - // aligns the pointer so it is friendly to GC - emit_write_bytecode_byte(emit, stack_adj, b); - emit->bytecode_offset = (size_t)MP_ALIGN(emit->bytecode_offset, sizeof(mp_obj_t)); - mp_obj_t *c = (mp_obj_t *)emit_get_cur_to_write_bytecode(emit, sizeof(mp_obj_t)); - // Verify that c is already uint-aligned - assert(c == MP_ALIGN(c, sizeof(mp_obj_t))); - *c = obj; - #endif + emit_write_bytecode_byte_const(emit, stack_adj, b, mp_emit_common_use_const_obj(emit->emit_common, obj)); } -STATIC void emit_write_bytecode_byte_raw_code(emit_t *emit, int stack_adj, byte b, mp_raw_code_t *rc) { - #if MICROPY_PERSISTENT_CODE +STATIC void emit_write_bytecode_byte_child(emit_t *emit, int stack_adj, byte b, mp_raw_code_t *rc) { emit_write_bytecode_byte_const(emit, stack_adj, b, - emit->scope->num_pos_args + emit->scope->num_kwonly_args - + emit->ct_num_obj + emit->ct_cur_raw_code++, (mp_uint_t)(uintptr_t)rc); - #else - // aligns the pointer so it is friendly to GC - emit_write_bytecode_byte(emit, stack_adj, b); - emit->bytecode_offset = (size_t)MP_ALIGN(emit->bytecode_offset, sizeof(void *)); - void **c = (void **)emit_get_cur_to_write_bytecode(emit, sizeof(void *)); - // Verify that c is already uint-aligned - assert(c == MP_ALIGN(c, sizeof(void *))); - *c = rc; - #endif + mp_emit_common_alloc_const_child(emit->emit_common, rc)); #if MICROPY_PY_SYS_SETTRACE rc->line_of_definition = emit->last_source_line; #endif } -// unsigned labels are relative to ip following this instruction, stored as 16 bits -STATIC void emit_write_bytecode_byte_unsigned_label(emit_t *emit, int stack_adj, byte b1, mp_uint_t label) { +// Emit a jump opcode to a destination label. +// The offset to the label is relative to the ip following this instruction. +// The offset is encoded as either 1 or 2 bytes, depending on how big it is. +// The encoding of this jump opcode can change size from one pass to the next, +// but it must only ever decrease in size on successive passes. +STATIC void emit_write_bytecode_byte_label(emit_t *emit, int stack_adj, byte b1, mp_uint_t label) { mp_emit_bc_adjust_stack_size(emit, stack_adj); - mp_uint_t bytecode_offset; - if (emit->pass < MP_PASS_EMIT) { - bytecode_offset = 0; - } else { - bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 3; + + // Determine if the jump offset is signed or unsigned, based on the opcode. + const bool is_signed = b1 <= MP_BC_POP_JUMP_IF_FALSE; + + // Default to a 2-byte encoding (the largest) with an unknown jump offset. + unsigned int jump_encoding_size = 1; + ssize_t bytecode_offset = 0; + + // Compute the jump size and offset only when code size is known. + if (emit->pass >= MP_PASS_CODE_SIZE) { + // The -2 accounts for this jump opcode taking 2 bytes (at least). + bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 2; + + // Check if the bytecode_offset is small enough to use a 1-byte encoding. + if ((is_signed && -64 <= bytecode_offset && bytecode_offset <= 63) + || (!is_signed && (size_t)bytecode_offset <= 127)) { + // Use a 1-byte jump offset. + jump_encoding_size = 0; + } + + // Adjust the offset depending on the size of the encoding of the offset. + bytecode_offset -= jump_encoding_size; + + assert(is_signed || bytecode_offset >= 0); } - byte *c = emit_get_cur_to_write_bytecode(emit, 3); - c[0] = b1; - c[1] = bytecode_offset; - c[2] = bytecode_offset >> 8; -} -// signed labels are relative to ip following this instruction, stored as 16 bits, in excess -STATIC void emit_write_bytecode_byte_signed_label(emit_t *emit, int stack_adj, byte b1, mp_uint_t label) { - mp_emit_bc_adjust_stack_size(emit, stack_adj); - int bytecode_offset; - if (emit->pass < MP_PASS_EMIT) { - bytecode_offset = 0; + // Emit the opcode. + byte *c = emit_get_cur_to_write_bytecode(emit, 2 + jump_encoding_size); + c[0] = b1; + if (jump_encoding_size == 0) { + if (is_signed) { + bytecode_offset += 0x40; + } + assert(0 <= bytecode_offset && bytecode_offset <= 0x7f); + c[1] = bytecode_offset; } else { - bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 3 + 0x8000; + if (is_signed) { + bytecode_offset += 0x4000; + } + if (emit->pass == MP_PASS_EMIT && !(0 <= bytecode_offset && bytecode_offset <= 0x7fff)) { + emit->overflow = true; + } + c[1] = 0x80 | (bytecode_offset & 0x7f); + c[2] = bytecode_offset >> 7; } - byte *c = emit_get_cur_to_write_bytecode(emit, 3); - c[0] = b1; - c[1] = bytecode_offset; - c[2] = bytecode_offset >> 8; } void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { @@ -315,14 +276,9 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { emit->scope = scope; emit->last_source_line_offset = 0; emit->last_source_line = 1; - #ifndef NDEBUG - // With debugging enabled labels are checked for unique assignment - if (pass < MP_PASS_EMIT && emit->label_offsets != NULL) { - memset(emit->label_offsets, -1, emit->max_num_labels * sizeof(mp_uint_t)); - } - #endif emit->bytecode_offset = 0; emit->code_info_offset = 0; + emit->overflow = false; // Write local state size, exception stack size, scope flags and number of arguments { @@ -343,27 +299,19 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { } // Write number of cells and size of the source code info - if (pass >= MP_PASS_CODE_SIZE) { - MP_BC_PRELUDE_SIZE_ENCODE(emit->n_info, emit->n_cell, emit_write_code_info_byte, emit); + if (emit->pass >= MP_PASS_CODE_SIZE) { + size_t n_info = emit->n_info; + size_t n_cell = emit->n_cell; + MP_BC_PRELUDE_SIZE_ENCODE(n_info, n_cell, emit_write_code_info_byte, emit); } emit->n_info = emit->code_info_offset; - // Write the name and source file of this function. + // Write the name of this function. emit_write_code_info_qstr(emit, scope->simple_name); - emit_write_code_info_qstr(emit, scope->source_file); - - #if MICROPY_PERSISTENT_CODE - emit->ct_cur_obj = 0; - emit->ct_cur_raw_code = 0; - #endif - - if (pass == MP_PASS_EMIT) { - // Write argument names (needed to resolve positional args passed as - // keywords). We store them as full word-sized objects for efficient access - // in mp_setup_code_state this is the start of the prelude and is guaranteed - // to be aligned on a word boundary. + // Write argument names, needed to resolve positional args passed as keywords. + { // For a given argument position (indexed by i) we need to find the // corresponding id_info which is a parameter, as it has the correct // qstr name to use as the argument name. Note that it's not a simple @@ -383,21 +331,19 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { break; } } - emit->const_table[i] = (mp_uint_t)MP_OBJ_NEW_QSTR(qst); + emit_write_code_info_qstr(emit, qst); } } } -void mp_emit_bc_end_pass(emit_t *emit) { +bool mp_emit_bc_end_pass(emit_t *emit) { if (emit->pass == MP_PASS_SCOPE) { - return; + return true; } // check stack is back to zero size assert(emit->stack_size == 0); - emit_write_code_info_byte(emit, 0); // end of line number info - // Calculate size of source code info section emit->n_info = emit->code_info_offset - emit->n_info; @@ -412,42 +358,43 @@ void mp_emit_bc_end_pass(emit_t *emit) { } } - #if MICROPY_PERSISTENT_CODE - assert(emit->pass <= MP_PASS_STACK_SIZE || (emit->ct_num_obj == emit->ct_cur_obj)); - emit->ct_num_obj = emit->ct_cur_obj; - #endif - if (emit->pass == MP_PASS_CODE_SIZE) { - #if !MICROPY_PERSISTENT_CODE - // so bytecode is aligned - emit->code_info_offset = (size_t)MP_ALIGN(emit->code_info_offset, sizeof(mp_uint_t)); - #endif - // calculate size of total code-info + bytecode, in bytes emit->code_info_size = emit->code_info_offset; emit->bytecode_size = emit->bytecode_offset; emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size); - #if MICROPY_PERSISTENT_CODE - emit->const_table = m_new0(mp_uint_t, - emit->scope->num_pos_args + emit->scope->num_kwonly_args - + emit->ct_cur_obj + emit->ct_cur_raw_code); - #else - emit->const_table = m_new0(mp_uint_t, - emit->scope->num_pos_args + emit->scope->num_kwonly_args); - #endif - } else if (emit->pass == MP_PASS_EMIT) { + // Code info and/or bytecode can shrink during this pass. + assert(emit->code_info_offset <= emit->code_info_size); + assert(emit->bytecode_offset <= emit->bytecode_size); + + if (emit->code_info_offset != emit->code_info_size + || emit->bytecode_offset != emit->bytecode_size) { + // Code info and/or bytecode changed size in this pass, so request the + // compiler to do another pass with these updated sizes. + emit->code_info_size = emit->code_info_offset; + emit->bytecode_size = emit->bytecode_offset; + return false; + } + + if (emit->overflow) { + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("bytecode overflow")); + } + + // Bytecode is finalised, assign it to the raw code object. mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base, #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS emit->code_info_size + emit->bytecode_size, #endif - emit->const_table, + emit->emit_common->children, #if MICROPY_PERSISTENT_CODE_SAVE - emit->ct_cur_obj, emit->ct_cur_raw_code, + emit->emit_common->ct_cur_child, #endif emit->scope->scope_flags); } + + return true; } bool mp_emit_bc_last_emit_was_return_value(emit_t *emit) { @@ -490,15 +437,16 @@ void mp_emit_bc_label_assign(emit_t *emit, mp_uint_t l) { if (emit->pass == MP_PASS_SCOPE) { return; } + + // Label offsets can change from one pass to the next, but they must only + // decrease (ie code can only shrink). There will be multiple MP_PASS_EMIT + // stages until the labels no longer change, which is when the code size + // stays constant after a MP_PASS_EMIT. assert(l < emit->max_num_labels); - if (emit->pass < MP_PASS_EMIT) { - // assign label offset - assert(emit->label_offsets[l] == (mp_uint_t)-1); - emit->label_offsets[l] = emit->bytecode_offset; - } else { - // ensure label offset has not changed from MP_PASS_CODE_SIZE to MP_PASS_EMIT - assert(emit->label_offsets[l] == emit->bytecode_offset); - } + assert(emit->pass == MP_PASS_STACK_SIZE || emit->bytecode_offset <= emit->label_offsets[l]); + + // Assign label offset. + emit->label_offsets[l] = emit->bytecode_offset; } void mp_emit_bc_import(emit_t *emit, qstr qst, int kind) { @@ -523,6 +471,7 @@ void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) { } void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg) { + assert(MP_SMALL_INT_FITS(arg)); if (-MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS <= arg && arg < MP_BC_LOAD_CONST_SMALL_INT_MULTI_NUM - MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS) { emit_write_bytecode_byte(emit, 1, @@ -646,22 +595,22 @@ void mp_emit_bc_rot_three(emit_t *emit) { } void mp_emit_bc_jump(emit_t *emit, mp_uint_t label) { - emit_write_bytecode_byte_signed_label(emit, 0, MP_BC_JUMP, label); + emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label); } void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label) { if (cond) { - emit_write_bytecode_byte_signed_label(emit, -1, MP_BC_POP_JUMP_IF_TRUE, label); + emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_TRUE, label); } else { - emit_write_bytecode_byte_signed_label(emit, -1, MP_BC_POP_JUMP_IF_FALSE, label); + emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_FALSE, label); } } void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label) { if (cond) { - emit_write_bytecode_byte_signed_label(emit, -1, MP_BC_JUMP_IF_TRUE_OR_POP, label); + emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_TRUE_OR_POP, label); } else { - emit_write_bytecode_byte_signed_label(emit, -1, MP_BC_JUMP_IF_FALSE_OR_POP, label); + emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_FALSE_OR_POP, label); } } @@ -675,9 +624,9 @@ void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_dept emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP); } } - emit_write_bytecode_byte_signed_label(emit, 0, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR); + emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR); } else { - emit_write_bytecode_byte_signed_label(emit, 0, MP_BC_UNWIND_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR); + emit_write_bytecode_byte_label(emit, 0, MP_BC_UNWIND_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR); emit_write_bytecode_raw_byte(emit, ((label & MP_EMIT_BREAK_FROM_FOR) ? 0x80 : 0) | except_depth); } } @@ -689,7 +638,7 @@ void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind) { // The SETUP_WITH opcode pops ctx_mgr from the top of the stack // and then pushes 3 entries: __exit__, ctx_mgr, as_value. int stack_adj = kind == MP_EMIT_SETUP_BLOCK_WITH ? 2 : 0; - emit_write_bytecode_byte_unsigned_label(emit, stack_adj, MP_BC_SETUP_WITH + kind, label); + emit_write_bytecode_byte_label(emit, stack_adj, MP_BC_SETUP_WITH + kind, label); } void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) { @@ -711,7 +660,7 @@ void mp_emit_bc_get_iter(emit_t *emit, bool use_stack) { } void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) { - emit_write_bytecode_byte_unsigned_label(emit, 1, MP_BC_FOR_ITER, label); + emit_write_bytecode_byte_label(emit, 1, MP_BC_FOR_ITER, label); } void mp_emit_bc_for_iter_end(emit_t *emit) { @@ -720,7 +669,7 @@ void mp_emit_bc_for_iter_end(emit_t *emit) { void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) { (void)within_exc_handler; - emit_write_bytecode_byte_unsigned_label(emit, 0, MP_BC_POP_EXCEPT_JUMP, label); + emit_write_bytecode_byte_label(emit, 0, MP_BC_POP_EXCEPT_JUMP, label); } void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) { @@ -783,28 +732,30 @@ void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) { void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) { if (n_pos_defaults == 0 && n_kw_defaults == 0) { - emit_write_bytecode_byte_raw_code(emit, 1, MP_BC_MAKE_FUNCTION, scope->raw_code); + emit_write_bytecode_byte_child(emit, 1, MP_BC_MAKE_FUNCTION, scope->raw_code); } else { - emit_write_bytecode_byte_raw_code(emit, -1, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code); + emit_write_bytecode_byte_child(emit, -1, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code); } } void mp_emit_bc_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) { if (n_pos_defaults == 0 && n_kw_defaults == 0) { int stack_adj = -n_closed_over + 1; - emit_write_bytecode_byte_raw_code(emit, stack_adj, MP_BC_MAKE_CLOSURE, scope->raw_code); + emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE, scope->raw_code); emit_write_bytecode_raw_byte(emit, n_closed_over); } else { assert(n_closed_over <= 255); int stack_adj = -2 - (mp_int_t)n_closed_over + 1; - emit_write_bytecode_byte_raw_code(emit, stack_adj, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code); + emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code); emit_write_bytecode_raw_byte(emit, n_closed_over); } } STATIC void emit_bc_call_function_method_helper(emit_t *emit, int stack_adj, mp_uint_t bytecode_base, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) { if (star_flags) { - stack_adj -= (int)n_positional + 2 * (int)n_keyword + 2; + // each positional arg is one object, each kwarg is two objects, the key + // and the value and one extra object for the star args bitmap. + stack_adj -= (int)n_positional + 2 * (int)n_keyword + 1; emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base + 1, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints? } else { stack_adj -= (int)n_positional + 2 * (int)n_keyword; diff --git a/py/emitcommon.c b/py/emitcommon.c index 177418c30ab64..679ef1d973b1b 100644 --- a/py/emitcommon.c +++ b/py/emitcommon.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,15 +27,76 @@ #include #include "py/emit.h" +#include "py/nativeglue.h" #if MICROPY_ENABLE_COMPILER +#if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE +qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst) { + mp_map_elem_t *elem = mp_map_lookup(&emit->qstr_map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); + if (elem->value == MP_OBJ_NULL) { + elem->value = MP_OBJ_NEW_SMALL_INT(emit->qstr_map.used - 1); + } + return MP_OBJ_SMALL_INT_VALUE(elem->value); +} +#endif + +// Compare two objects for strict equality, including equality of type. This is +// different to the semantics of mp_obj_equal which, eg, has (True,) == (1.0,). +static bool strictly_equal(mp_obj_t a, mp_obj_t b) { + if (a == b) { + return true; + } + + #if MICROPY_EMIT_NATIVE + if (a == MP_OBJ_FROM_PTR(&mp_fun_table) || b == MP_OBJ_FROM_PTR(&mp_fun_table)) { + return false; + } + #endif + + const mp_obj_type_t *a_type = mp_obj_get_type(a); + const mp_obj_type_t *b_type = mp_obj_get_type(b); + if (a_type != b_type) { + return false; + } + if (a_type == &mp_type_tuple) { + mp_obj_tuple_t *a_tuple = MP_OBJ_TO_PTR(a); + mp_obj_tuple_t *b_tuple = MP_OBJ_TO_PTR(b); + if (a_tuple->len != b_tuple->len) { + return false; + } + for (size_t i = 0; i < a_tuple->len; ++i) { + if (!strictly_equal(a_tuple->items[i], b_tuple->items[i])) { + return false; + } + } + return true; + } else { + return mp_obj_equal(a, b); + } +} + +size_t mp_emit_common_use_const_obj(mp_emit_common_t *emit, mp_obj_t const_obj) { + for (size_t i = 0; i < emit->const_obj_list.len; ++i) { + if (strictly_equal(emit->const_obj_list.items[i], const_obj)) { + return i; + } + } + mp_obj_list_append(MP_OBJ_FROM_PTR(&emit->const_obj_list), const_obj); + return emit->const_obj_list.len - 1; +} + void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst) { // name adding/lookup id_info_t *id = scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT); - if (SCOPE_IS_FUNC_LIKE(scope->kind) && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) { - // rebind as a local variable - id->kind = ID_INFO_KIND_LOCAL; + if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) { + if (SCOPE_IS_FUNC_LIKE(scope->kind)) { + // rebind as a local variable + id->kind = ID_INFO_KIND_LOCAL; + } else { + // mark this as assigned, to prevent it from being closed over + id->kind = ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED; + } } } @@ -46,7 +107,7 @@ void mp_emit_common_id_op(emit_t *emit, const mp_emit_method_table_id_ops_t *emi assert(id != NULL); // call the emit backend with the correct code - if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) { + if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED) { emit_method_table->global(emit, qst, MP_EMIT_IDOP_GLOBAL_NAME); } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) { emit_method_table->global(emit, qst, MP_EMIT_IDOP_GLOBAL_GLOBAL); diff --git a/py/emitglue.c b/py/emitglue.c index e701d0808f718..d4d8439881a4d 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +34,7 @@ #include "py/emitglue.h" #include "py/runtime0.h" #include "py/bc.h" +#include "py/objfun.h" #include "py/profile.h" #if MICROPY_DEBUG_VERBOSE // print debugging info @@ -63,20 +64,22 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS size_t len, #endif - const mp_uint_t *const_table, + mp_raw_code_t **children, #if MICROPY_PERSISTENT_CODE_SAVE - uint16_t n_obj, uint16_t n_raw_code, + size_t n_children, #endif mp_uint_t scope_flags) { rc->kind = MP_CODE_BYTECODE; rc->scope_flags = scope_flags; rc->fun_data = code; - rc->const_table = const_table; - #if MICROPY_PERSISTENT_CODE_SAVE + #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS rc->fun_data_len = len; - rc->n_obj = n_obj; - rc->n_raw_code = n_raw_code; + #endif + rc->children = children; + + #if MICROPY_PERSISTENT_CODE_SAVE + rc->n_children = n_children; #endif #if MICROPY_PY_SYS_SETTRACE @@ -85,26 +88,21 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, #endif #ifdef DEBUG_PRINT - #if !MICROPY_DEBUG_PRINTERS + #if !(MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS) const size_t len = 0; #endif DEBUG_printf("assign byte code: code=%p len=" UINT_FMT " flags=%x\n", code, len, (uint)scope_flags); #endif - #if MICROPY_DEBUG_PRINTERS - if (mp_verbose_flag >= 2) { - mp_bytecode_print(&mp_plat_print, rc, code, len, const_table); - } - #endif } #if MICROPY_EMIT_MACHINE_CODE -void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, const mp_uint_t *const_table, +void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, + mp_raw_code_t **children, #if MICROPY_PERSISTENT_CODE_SAVE + size_t n_children, uint16_t prelude_offset, - uint16_t n_obj, uint16_t n_raw_code, - uint16_t n_qstr, mp_qstr_link_entry_t *qstr_link, #endif - mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig) { + mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t type_sig) { assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM); @@ -135,20 +133,22 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void rc->kind = kind; rc->scope_flags = scope_flags; - rc->n_pos_args = n_pos_args; rc->fun_data = fun_data; - rc->const_table = const_table; - rc->type_sig = type_sig; - #if MICROPY_PERSISTENT_CODE_SAVE + #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS rc->fun_data_len = fun_len; + #endif + rc->children = children; + + #if MICROPY_PERSISTENT_CODE_SAVE + rc->n_children = n_children; rc->prelude_offset = prelude_offset; - rc->n_obj = n_obj; - rc->n_raw_code = n_raw_code; - rc->n_qstr = n_qstr; - rc->qstr_link = qstr_link; #endif + // These two entries are only needed for MP_CODE_NATIVE_ASM. + rc->n_pos_args = n_pos_args; + rc->type_sig = type_sig; + #ifdef DEBUG_PRINT DEBUG_printf("assign native: kind=%d fun=%p len=" UINT_FMT " n_pos_args=" UINT_FMT " flags=%x\n", kind, fun_data, fun_len, n_pos_args, (uint)scope_flags); for (mp_uint_t i = 0; i < fun_len; i++) { @@ -170,15 +170,15 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void } #endif -mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args) { +mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, const mp_module_context_t *context, const mp_obj_t *def_args) { DEBUG_OP_printf("make_function_from_raw_code %p\n", rc); assert(rc != NULL); // def_args must be MP_OBJ_NULL or a tuple - assert(def_args == MP_OBJ_NULL || mp_obj_is_type(def_args, &mp_type_tuple)); + assert(def_args == NULL || def_args[0] == MP_OBJ_NULL || mp_obj_is_type(def_args[0], &mp_type_tuple)); // def_kw_args must be MP_OBJ_NULL or a dict - assert(def_kw_args == MP_OBJ_NULL || mp_obj_is_type(def_kw_args, &mp_type_dict)); + assert(def_args == NULL || def_args[1] == MP_OBJ_NULL || mp_obj_is_type(def_args[1], &mp_type_dict)); // make the function, depending on the raw code kind mp_obj_t fun; @@ -186,7 +186,13 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar #if MICROPY_EMIT_NATIVE case MP_CODE_NATIVE_PY: case MP_CODE_NATIVE_VIPER: - fun = mp_obj_new_fun_native(def_args, def_kw_args, rc->fun_data, rc->const_table); + fun = mp_obj_new_fun_native(def_args, rc->fun_data, context, rc->children); + // Check for a generator function, and if so change the type of the object + if ((rc->scope_flags & MP_SCOPE_FLAG_ASYNC) != 0) { + ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_native_coro_wrap; + } else if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) { + ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_native_gen_wrap; + } break; #endif #if MICROPY_EMIT_INLINE_ASM @@ -197,35 +203,40 @@ mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_ar default: // rc->kind should always be set and BYTECODE is the only remaining case assert(rc->kind == MP_CODE_BYTECODE); - fun = mp_obj_new_fun_bc(def_args, def_kw_args, rc->fun_data, rc->const_table); - break; - } - - // check for generator functions and if so wrap in generator object - if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) { - fun = mp_obj_new_gen_wrap(fun, (rc->scope_flags & MP_SCOPE_FLAG_ASYNC) != 0); - } + fun = mp_obj_new_fun_bc(def_args, rc->fun_data, context, rc->children); + // check for generator functions and if so change the type of the object + // A generator is MP_SCOPE_FLAG_ASYNC | MP_SCOPE_FLAG_GENERATOR, + // so check for ASYNC first. + #if MICROPY_PY_ASYNC_AWAIT + if ((rc->scope_flags & MP_SCOPE_FLAG_ASYNC) != 0) { + ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_coro_wrap; + } else + #endif + if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) { + ((mp_obj_base_t *)MP_OBJ_TO_PTR(fun))->type = &mp_type_gen_wrap; + } + + #if MICROPY_PY_SYS_SETTRACE + mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t *)MP_OBJ_TO_PTR(fun); + self_fun->rc = rc; + #endif - #if MICROPY_PY_SYS_SETTRACE - if (rc->kind == MP_CODE_BYTECODE) { - mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t *)MP_OBJ_TO_PTR(fun); - self_fun->rc = rc; + break; } - #endif return fun; } -mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args) { +mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, const mp_module_context_t *context, mp_uint_t n_closed_over, const mp_obj_t *args) { DEBUG_OP_printf("make_closure_from_raw_code %p " UINT_FMT " %p\n", rc, n_closed_over, args); // make function object mp_obj_t ffun; if (n_closed_over & 0x100) { // default positional and keyword args given - ffun = mp_make_function_from_raw_code(rc, args[0], args[1]); + ffun = mp_make_function_from_raw_code(rc, context, args); } else { // default positional and keyword args not given - ffun = mp_make_function_from_raw_code(rc, MP_OBJ_NULL, MP_OBJ_NULL); + ffun = mp_make_function_from_raw_code(rc, context, NULL); } // wrap function in closure object return mp_obj_new_closure(ffun, n_closed_over & 0xff, args + ((n_closed_over >> 7) & 2)); diff --git a/py/emitglue.h b/py/emitglue.h index cbe69d6e449b5..4ddf74011fa70 100644 --- a/py/emitglue.h +++ b/py/emitglue.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,21 +49,20 @@ typedef enum { MP_CODE_NATIVE_ASM, } mp_raw_code_kind_t; -typedef struct _mp_qstr_link_entry_t { - uint16_t off; - uint16_t qst; -} mp_qstr_link_entry_t; - +// compiled bytecode: instance in RAM, referenced by outer scope, usually freed after first (and only) use +// mpy file: instance in RAM, created when .mpy file is loaded (same comments as above) +// frozen: instance in ROM typedef struct _mp_raw_code_t { - uint8_t kind; // of type mp_raw_code_kind_t - uint8_t scope_flags; - uint16_t n_pos_args; + mp_uint_t kind : 3; // of type mp_raw_code_kind_t + mp_uint_t scope_flags : 7; + mp_uint_t n_pos_args : 11; const void *fun_data; - const mp_uint_t *const_table; + #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS + size_t fun_data_len; // so mp_raw_code_save and mp_bytecode_print work + #endif + struct _mp_raw_code_t **children; #if MICROPY_PERSISTENT_CODE_SAVE - size_t fun_data_len; - uint16_t n_obj; - uint16_t n_raw_code; + size_t n_children; #if MICROPY_PY_SYS_SETTRACE mp_bytecode_prelude_t prelude; // line_of_definition is a Python source line where the raw_code was @@ -74,8 +73,6 @@ typedef struct _mp_raw_code_t { #endif #if MICROPY_EMIT_MACHINE_CODE uint16_t prelude_offset; - uint16_t n_qstr; - mp_qstr_link_entry_t *qstr_link; #endif #endif #if MICROPY_EMIT_MACHINE_CODE @@ -89,22 +86,21 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS size_t len, #endif - const mp_uint_t *const_table, + mp_raw_code_t **children, #if MICROPY_PERSISTENT_CODE_SAVE - uint16_t n_obj, uint16_t n_raw_code, + size_t n_children, #endif mp_uint_t scope_flags); void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void *fun_data, mp_uint_t fun_len, - const mp_uint_t *const_table, + mp_raw_code_t **children, #if MICROPY_PERSISTENT_CODE_SAVE + size_t n_children, uint16_t prelude_offset, - uint16_t n_obj, uint16_t n_raw_code, - uint16_t n_qstr, mp_qstr_link_entry_t *qstr_link, #endif - mp_uint_t n_pos_args, mp_uint_t scope_flags, mp_uint_t type_sig); + mp_uint_t scope_flags, mp_uint_t n_pos_args, mp_uint_t type_sig); -mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args); -mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args); +mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, const mp_module_context_t *context, const mp_obj_t *def_args); +mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, const mp_module_context_t *context, mp_uint_t n_closed_over, const mp_obj_t *args); #endif // MICROPY_INCLUDED_PY_EMITGLUE_H diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 65168a5211df7..4bde921b99a1e 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -59,6 +59,21 @@ struct _emit_inline_asm_t { qstr *label_lookup; }; +#if MICROPY_DYNAMIC_COMPILER + +static inline bool emit_inline_thumb_allow_float(emit_inline_asm_t *emit) { + return MP_NATIVE_ARCH_ARMV7EMSP <= mp_dynamic_compiler.native_arch + && mp_dynamic_compiler.native_arch <= MP_NATIVE_ARCH_ARMV7EMDP; +} + +#else + +static inline bool emit_inline_thumb_allow_float(emit_inline_asm_t *emit) { + return MICROPY_EMIT_INLINE_THUMB_FLOAT; +} + +#endif + STATIC void emit_inline_thumb_error_msg(emit_inline_asm_t *emit, const compressed_string_t *msg) { *emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg); } @@ -216,7 +231,6 @@ STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp return 0; } -#if MICROPY_EMIT_INLINE_THUMB_FLOAT STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { const char *reg_str = get_arg_str(pn); if (reg_str[0] == 's' && reg_str[1] != '\0') { @@ -243,7 +257,6 @@ STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_pars MP_ERROR_TEXT("'%s' expects an FPU register"), op)); return 0; } -#endif STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { // a register list looks like {r0, r1, r2} and is parsed as a Python set @@ -409,10 +422,10 @@ STATIC const format_9_10_op_t format_9_10_op_table[] = { }; #undef X -#if MICROPY_EMIT_INLINE_THUMB_FLOAT // actual opcodes are: 0xee00 | op.hi_nibble, 0x0a00 | op.lo_nibble -typedef struct _format_vfp_op_t { byte op; - char name[3]; +typedef struct _format_vfp_op_t { + byte op; + char name[3]; } format_vfp_op_t; STATIC const format_vfp_op_t format_vfp_op_table[] = { { 0x30, "add" }, @@ -420,10 +433,9 @@ STATIC const format_vfp_op_t format_vfp_op_table[] = { { 0x20, "mul" }, { 0x80, "div" }, }; -#endif // shorthand alias for whether we allow ARMv7-M instructions -#define ARMV7M MICROPY_EMIT_INLINE_THUMB_ARMV7M +#define ARMV7M asm_thumb_allow_armv7m(&emit->as) STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args) { // TODO perhaps make two tables: @@ -439,8 +451,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a size_t op_len; const char *op_str = (const char *)qstr_data(op, &op_len); - #if MICROPY_EMIT_INLINE_THUMB_FLOAT - if (op_str[0] == 'v') { + if (emit_inline_thumb_allow_float(emit) && op_str[0] == 'v') { // floating point operations if (n_args == 2) { mp_uint_t op_code = 0x0ac0, op_code_hi; @@ -535,7 +546,6 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a } return; } - #endif if (n_args == 0) { if (op == MP_QSTR_nop) { @@ -621,8 +631,13 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a asm_thumb_op16(&emit->as, ASM_THUMB_OP_CPSIE_I); } else if (op == MP_QSTR_push) { mp_uint_t reglist = get_arg_reglist(emit, op_str, pn_args[0]); - if ((reglist & 0xff00) == 0) { - asm_thumb_op16(&emit->as, 0xb400 | reglist); + if ((reglist & 0xbf00) == 0) { + if ((reglist & (1 << 14)) == 0) { + asm_thumb_op16(&emit->as, 0xb400 | reglist); + } else { + // 16-bit encoding for pushing low registers and LR + asm_thumb_op16(&emit->as, 0xb500 | (reglist & 0xff)); + } } else { if (!ARMV7M) { goto unknown_op; @@ -631,8 +646,13 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a } } else if (op == MP_QSTR_pop) { mp_uint_t reglist = get_arg_reglist(emit, op_str, pn_args[0]); - if ((reglist & 0xff00) == 0) { - asm_thumb_op16(&emit->as, 0xbc00 | reglist); + if ((reglist & 0x7f00) == 0) { + if ((reglist & (1 << 15)) == 0) { + asm_thumb_op16(&emit->as, 0xbc00 | reglist); + } else { + // 16-bit encoding for popping low registers and PC, i.e., returning + asm_thumb_op16(&emit->as, 0xbd00 | (reglist & 0xff)); + } } else { if (!ARMV7M) { goto unknown_op; @@ -705,24 +725,23 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a } else if (op == MP_QSTR_sub) { op_code = ASM_THUMB_FORMAT_3_SUB; goto op_format_3; - #if ARMV7M - } else if (op == MP_QSTR_movw) { + } else if (ARMV7M && op == MP_QSTR_movw) { op_code = ASM_THUMB_OP_MOVW; mp_uint_t reg_dest; op_movw_movt: reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15); int i_src = get_arg_i(emit, op_str, pn_args[1], 0xffff); asm_thumb_mov_reg_i16(&emit->as, op_code, reg_dest, i_src); - } else if (op == MP_QSTR_movt) { + } else if (ARMV7M && op == MP_QSTR_movt) { op_code = ASM_THUMB_OP_MOVT; goto op_movw_movt; - } else if (op == MP_QSTR_movwt) { + } else if (ARMV7M && op == MP_QSTR_movwt) { // this is a convenience instruction mp_uint_t reg_dest = get_arg_reg(emit, op_str, pn_args[0], 15); uint32_t i_src = get_arg_i(emit, op_str, pn_args[1], 0xffffffff); asm_thumb_mov_reg_i16(&emit->as, ASM_THUMB_OP_MOVW, reg_dest, i_src & 0xffff); asm_thumb_mov_reg_i16(&emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0xffff); - } else if (op == MP_QSTR_ldrex) { + } else if (ARMV7M && op == MP_QSTR_ldrex) { mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15); mp_parse_node_t pn_base, pn_offset; if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) { @@ -730,7 +749,6 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a mp_uint_t i8 = get_arg_i(emit, op_str, pn_offset, 0xff) >> 2; asm_thumb_op32(&emit->as, 0xe850 | r_base, 0x0f00 | (r_dest << 12) | i8); } - #endif } else { // search table for ldr/str instructions for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(format_9_10_op_table); i++) { diff --git a/py/emitinlinextensa.c b/py/emitinlinextensa.c index 17b91163f1f65..f044cfd094550 100644 --- a/py/emitinlinextensa.c +++ b/py/emitinlinextensa.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2013-2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/emitnarm.c b/py/emitnarm.c index 8297ad61921a8..59075b6074a6a 100644 --- a/py/emitnarm.c +++ b/py/emitnarm.c @@ -10,8 +10,6 @@ // Word indices of REG_LOCAL_x in nlr_buf_t #define NLR_BUF_IDX_LOCAL_1 (3) // r4 -#define NLR_BUF_IDX_LOCAL_2 (4) // r5 -#define NLR_BUF_IDX_LOCAL_3 (5) // r6 #define N_ARM (1) #define EXPORT_FUN(name) emit_native_arm_##name diff --git a/py/emitnative.c b/py/emitnative.c index 7d615d58161f1..9fafa1104a15c 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -48,6 +48,7 @@ #include "py/emit.h" #include "py/nativeglue.h" +#include "py/objfun.h" #include "py/objstr.h" #if MICROPY_DEBUG_VERBOSE // print debugging info @@ -57,6 +58,7 @@ #define DEBUG_printf(...) (void)0 #endif +// CIRCUITPY: force definitions #ifndef N_X64 #define N_X64 (0) #endif @@ -90,20 +92,26 @@ // C stack layout for native functions: // 0: nlr_buf_t [optional] -// emit->code_state_start: mp_code_state_t +// return_value [optional word] +// exc_handler_unwind [optional word] +// emit->code_state_start: mp_code_state_native_t // emit->stack_start: Python object stack | emit->n_state // locals (reversed, L0 at end) | // // C stack layout for native generator functions: // 0=emit->stack_start: nlr_buf_t +// return_value +// exc_handler_unwind [optional word] // // Then REG_GENERATOR_STATE points to: -// 0=emit->code_state_start: mp_code_state_t +// 0=emit->code_state_start: mp_code_state_native_t // emit->stack_start: Python object stack | emit->n_state // locals (reversed, L0 at end) | // // C stack layout for viper functions: // 0: nlr_buf_t [optional] +// return_value [optional word] +// exc_handler_unwind [optional word] // emit->code_state_start: fun_obj, old_globals [optional] // emit->stack_start: Python object stack | emit->n_state // locals (reversed, L0 at end) | @@ -115,14 +123,18 @@ #else #define SIZEOF_NLR_BUF (sizeof(nlr_buf_t) / sizeof(uintptr_t)) #endif -#define SIZEOF_CODE_STATE (sizeof(mp_code_state_t) / sizeof(uintptr_t)) -#define OFFSETOF_CODE_STATE_STATE (offsetof(mp_code_state_t, state) / sizeof(uintptr_t)) -#define OFFSETOF_CODE_STATE_FUN_BC (offsetof(mp_code_state_t, fun_bc) / sizeof(uintptr_t)) -#define OFFSETOF_CODE_STATE_IP (offsetof(mp_code_state_t, ip) / sizeof(uintptr_t)) -#define OFFSETOF_CODE_STATE_SP (offsetof(mp_code_state_t, sp) / sizeof(uintptr_t)) -#define OFFSETOF_OBJ_FUN_BC_GLOBALS (offsetof(mp_obj_fun_bc_t, globals) / sizeof(uintptr_t)) +#define SIZEOF_CODE_STATE (sizeof(mp_code_state_native_t) / sizeof(uintptr_t)) +#define OFFSETOF_CODE_STATE_STATE (offsetof(mp_code_state_native_t, state) / sizeof(uintptr_t)) +#define OFFSETOF_CODE_STATE_FUN_BC (offsetof(mp_code_state_native_t, fun_bc) / sizeof(uintptr_t)) +#define OFFSETOF_CODE_STATE_IP (offsetof(mp_code_state_native_t, ip) / sizeof(uintptr_t)) +#define OFFSETOF_CODE_STATE_SP (offsetof(mp_code_state_native_t, sp) / sizeof(uintptr_t)) +#define OFFSETOF_CODE_STATE_N_STATE (offsetof(mp_code_state_native_t, n_state) / sizeof(uintptr_t)) +#define OFFSETOF_OBJ_FUN_BC_CONTEXT (offsetof(mp_obj_fun_bc_t, context) / sizeof(uintptr_t)) +#define OFFSETOF_OBJ_FUN_BC_CHILD_TABLE (offsetof(mp_obj_fun_bc_t, child_table) / sizeof(uintptr_t)) #define OFFSETOF_OBJ_FUN_BC_BYTECODE (offsetof(mp_obj_fun_bc_t, bytecode) / sizeof(uintptr_t)) -#define OFFSETOF_OBJ_FUN_BC_CONST_TABLE (offsetof(mp_obj_fun_bc_t, const_table) / sizeof(uintptr_t)) +#define OFFSETOF_MODULE_CONTEXT_QSTR_TABLE (offsetof(mp_module_context_t, constants.qstr_table) / sizeof(uintptr_t)) +#define OFFSETOF_MODULE_CONTEXT_OBJ_TABLE (offsetof(mp_module_context_t, constants.obj_table) / sizeof(uintptr_t)) +#define OFFSETOF_MODULE_CONTEXT_GLOBALS (offsetof(mp_module_context_t, module.globals) / sizeof(uintptr_t)) // If not already defined, set parent args to same as child call registers #ifndef REG_PARENT_RET @@ -144,6 +156,9 @@ #define NEED_GLOBAL_EXC_HANDLER(emit) ((emit)->scope->exc_stack_size > 0 \ || ((emit)->scope->scope_flags & (MP_SCOPE_FLAG_GENERATOR | MP_SCOPE_FLAG_REFGLOBALS))) +// Whether a slot is needed to store LOCAL_IDX_EXC_HANDLER_UNWIND +#define NEED_EXC_HANDLER_UNWIND(emit) ((emit)->scope->exc_stack_size > 0) + // Whether registers can be used to store locals (only true if there are no // exception handlers, because otherwise an nlr_jump will restore registers to // their state at the start of the function and updates to locals will be lost) @@ -152,14 +167,41 @@ // Indices within the local C stack for various variables #define LOCAL_IDX_EXC_VAL(emit) (NLR_BUF_IDX_RET_VAL) #define LOCAL_IDX_EXC_HANDLER_PC(emit) (NLR_BUF_IDX_LOCAL_1) -#define LOCAL_IDX_EXC_HANDLER_UNWIND(emit) (NLR_BUF_IDX_LOCAL_2) -#define LOCAL_IDX_RET_VAL(emit) (NLR_BUF_IDX_LOCAL_3) +#define LOCAL_IDX_EXC_HANDLER_UNWIND(emit) (SIZEOF_NLR_BUF + 1) // this needs a dedicated variable outside nlr_buf_t +#define LOCAL_IDX_RET_VAL(emit) (SIZEOF_NLR_BUF) // needed when NEED_GLOBAL_EXC_HANDLER is true #define LOCAL_IDX_FUN_OBJ(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_FUN_BC) #define LOCAL_IDX_OLD_GLOBALS(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_IP) #define LOCAL_IDX_GEN_PC(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_IP) #define LOCAL_IDX_LOCAL_VAR(emit, local_num) ((emit)->stack_start + (emit)->n_state - 1 - (local_num)) +#if MICROPY_PERSISTENT_CODE_SAVE + +// When building with the ability to save native code to .mpy files: +// - Qstrs are indirect via qstr_table, and REG_LOCAL_3 always points to qstr_table. +// - In a generator no registers are used to store locals, and REG_LOCAL_2 points to the generator state. +// - At most 2 registers hold local variables (see CAN_USE_REGS_FOR_LOCALS for when this is possible). + +#define REG_GENERATOR_STATE (REG_LOCAL_2) +#define REG_QSTR_TABLE (REG_LOCAL_3) +#define MAX_REGS_FOR_LOCAL_VARS (2) + +STATIC const uint8_t reg_local_table[MAX_REGS_FOR_LOCAL_VARS] = {REG_LOCAL_1, REG_LOCAL_2}; + +#else + +// When building without the ability to save native code to .mpy files: +// - Qstrs values are written directly into the machine code. +// - In a generator no registers are used to store locals, and REG_LOCAL_3 points to the generator state. +// - At most 3 registers hold local variables (see CAN_USE_REGS_FOR_LOCALS for when this is possible). + #define REG_GENERATOR_STATE (REG_LOCAL_3) +#define MAX_REGS_FOR_LOCAL_VARS (3) + +STATIC const uint8_t reg_local_table[MAX_REGS_FOR_LOCAL_VARS] = {REG_LOCAL_1, REG_LOCAL_2, REG_LOCAL_3}; + +#endif + +#define REG_LOCAL_LAST (reg_local_table[MAX_REGS_FOR_LOCAL_VARS - 1]) #define EMIT_NATIVE_VIPER_TYPE_ERROR(emit, ...) do { \ *emit->error_slot = mp_obj_new_exception_msg_varg(&mp_type_ViperTypeError, __VA_ARGS__); \ @@ -233,6 +275,7 @@ typedef struct _exc_stack_entry_t { } exc_stack_entry_t; struct _emit_t { + mp_emit_common_t *emit_common; mp_obj_t *error_slot; uint *label_slot; uint exit_label; @@ -253,23 +296,15 @@ struct _emit_t { exc_stack_entry_t *exc_stack; int prelude_offset; + int prelude_ptr_index; int start_offset; int n_state; uint16_t code_state_start; uint16_t stack_start; int stack_size; + uint16_t n_info; uint16_t n_cell; - uint16_t const_table_cur_obj; - uint16_t const_table_num_obj; - uint16_t const_table_cur_raw_code; - mp_uint_t *const_table; - - #if MICROPY_PERSISTENT_CODE_SAVE - uint16_t qstr_link_cur; - mp_qstr_link_entry_t *qstr_link; - #endif - bool last_emit_was_return_value; scope_t *scope; @@ -277,14 +312,14 @@ struct _emit_t { ASM_T *as; }; -STATIC const uint8_t reg_local_table[REG_LOCAL_NUM] = {REG_LOCAL_1, REG_LOCAL_2, REG_LOCAL_3}; - +STATIC void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj); STATIC void emit_native_global_exc_entry(emit_t *emit); STATIC void emit_native_global_exc_exit(emit_t *emit); STATIC void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj); -emit_t *EXPORT_FUN(new)(mp_obj_t * error_slot, uint *label_slot, mp_uint_t max_num_labels) { +emit_t *EXPORT_FUN(new)(mp_emit_common_t * emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels) { emit_t *emit = m_new0(emit_t, 1); + emit->emit_common = emit_common; emit->error_slot = error_slot; emit->label_slot = label_slot; emit->stack_info_alloc = 8; @@ -338,12 +373,7 @@ STATIC void emit_native_mov_reg_state_addr(emit_t *emit, int reg_dest, int local STATIC void emit_native_mov_reg_qstr(emit_t *emit, int arg_reg, qstr qst) { #if MICROPY_PERSISTENT_CODE_SAVE - size_t loc = ASM_MOV_REG_IMM_FIX_U16(emit->as, arg_reg, qst); - size_t link_idx = emit->qstr_link_cur++; - if (emit->pass == MP_PASS_EMIT) { - emit->qstr_link[link_idx].off = loc << 2 | 1; - emit->qstr_link[link_idx].qst = qst; - } + ASM_LOAD16_REG_REG_OFFSET(emit->as, arg_reg, REG_QSTR_TABLE, mp_emit_common_use_qstr(emit->emit_common, qst)); #else ASM_MOV_REG_IMM(emit->as, arg_reg, qst); #endif @@ -351,12 +381,7 @@ STATIC void emit_native_mov_reg_qstr(emit_t *emit, int arg_reg, qstr qst) { STATIC void emit_native_mov_reg_qstr_obj(emit_t *emit, int reg_dest, qstr qst) { #if MICROPY_PERSISTENT_CODE_SAVE - size_t loc = ASM_MOV_REG_IMM_FIX_WORD(emit->as, reg_dest, (mp_uint_t)MP_OBJ_NEW_QSTR(qst)); - size_t link_idx = emit->qstr_link_cur++; - if (emit->pass == MP_PASS_EMIT) { - emit->qstr_link[link_idx].off = loc << 2 | 2; - emit->qstr_link[link_idx].qst = qst; - } + emit_load_reg_with_object(emit, reg_dest, MP_OBJ_NEW_QSTR(qst)); #else ASM_MOV_REG_IMM(emit->as, reg_dest, (mp_uint_t)MP_OBJ_NEW_QSTR(qst)); #endif @@ -368,33 +393,12 @@ STATIC void emit_native_mov_reg_qstr_obj(emit_t *emit, int reg_dest, qstr qst) { emit_native_mov_state_reg((emit), (local_num), (reg_temp)); \ } while (false) -#define emit_native_mov_state_imm_fix_u16_via(emit, local_num, imm, reg_temp) \ - do { \ - ASM_MOV_REG_IMM_FIX_U16((emit)->as, (reg_temp), (imm)); \ - emit_native_mov_state_reg((emit), (local_num), (reg_temp)); \ - } while (false) - -#define emit_native_mov_state_imm_fix_word_via(emit, local_num, imm, reg_temp) \ - do { \ - ASM_MOV_REG_IMM_FIX_WORD((emit)->as, (reg_temp), (imm)); \ - emit_native_mov_state_reg((emit), (local_num), (reg_temp)); \ - } while (false) - STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { DEBUG_printf("start_pass(pass=%u, scope=%p)\n", pass, scope); emit->pass = pass; emit->do_viper_types = scope->emit_options == MP_EMIT_OPT_VIPER; emit->stack_size = 0; - #if N_PRELUDE_AS_BYTES_OBJ - emit->const_table_cur_obj = emit->do_viper_types ? 0 : 1; // reserve first obj for prelude bytes obj - #else - emit->const_table_cur_obj = 0; - #endif - emit->const_table_cur_raw_code = 0; - #if MICROPY_PERSISTENT_CODE_SAVE - emit->qstr_link_cur = 0; - #endif emit->last_emit_was_return_value = false; emit->scope = scope; @@ -442,12 +446,18 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop // generate code for entry to function - // Work out start of code state (mp_code_state_t or reduced version for viper) + // Work out start of code state (mp_code_state_native_t or reduced version for viper) emit->code_state_start = 0; if (NEED_GLOBAL_EXC_HANDLER(emit)) { - emit->code_state_start = SIZEOF_NLR_BUF; + emit->code_state_start = SIZEOF_NLR_BUF; // for nlr_buf_t + emit->code_state_start += 1; // for return_value + if (NEED_EXC_HANDLER_UNWIND(emit)) { + emit->code_state_start += 1; + } } + size_t fun_table_off = mp_emit_common_use_const_obj(emit->emit_common, MP_OBJ_FROM_PTR(&mp_fun_table)); + if (emit->do_viper_types) { // Work out size of state (locals plus stack) // n_state counts all stack and locals, even those in registers @@ -455,11 +465,11 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop int num_locals_in_regs = 0; if (CAN_USE_REGS_FOR_LOCALS(emit)) { num_locals_in_regs = scope->num_locals; - if (num_locals_in_regs > REG_LOCAL_NUM) { - num_locals_in_regs = REG_LOCAL_NUM; + if (num_locals_in_regs > MAX_REGS_FOR_LOCAL_VARS) { + num_locals_in_regs = MAX_REGS_FOR_LOCAL_VARS; } - // Need a spot for REG_LOCAL_3 if 4 or more args (see below) - if (scope->num_pos_args >= 4) { + // Need a spot for REG_LOCAL_LAST (see below) + if (scope->num_pos_args >= MAX_REGS_FOR_LOCAL_VARS + 1) { --num_locals_in_regs; } } @@ -483,23 +493,27 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop #endif // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_LOCAL_3, REG_PARENT_ARG_1, OFFSETOF_OBJ_FUN_BC_CONST_TABLE); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_LOCAL_3, 0); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_PARENT_ARG_1, OFFSETOF_OBJ_FUN_BC_CONTEXT); + #if MICROPY_PERSISTENT_CODE_SAVE + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_QSTR_TABLE, REG_FUN_TABLE, OFFSETOF_MODULE_CONTEXT_QSTR_TABLE); + #endif + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_FUN_TABLE, OFFSETOF_MODULE_CONTEXT_OBJ_TABLE); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_FUN_TABLE, fun_table_off); // Store function object (passed as first arg) to stack if needed if (NEED_FUN_OBJ(emit)) { ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_FUN_OBJ(emit), REG_PARENT_ARG_1); } - // Put n_args in REG_ARG_1, n_kw in REG_ARG_2, args array in REG_LOCAL_3 + // Put n_args in REG_ARG_1, n_kw in REG_ARG_2, args array in REG_LOCAL_LAST #if N_X86 asm_x86_mov_arg_to_r32(emit->as, 1, REG_ARG_1); asm_x86_mov_arg_to_r32(emit->as, 2, REG_ARG_2); - asm_x86_mov_arg_to_r32(emit->as, 3, REG_LOCAL_3); + asm_x86_mov_arg_to_r32(emit->as, 3, REG_LOCAL_LAST); #else ASM_MOV_REG_REG(emit->as, REG_ARG_1, REG_PARENT_ARG_2); ASM_MOV_REG_REG(emit->as, REG_ARG_2, REG_PARENT_ARG_3); - ASM_MOV_REG_REG(emit->as, REG_LOCAL_3, REG_PARENT_ARG_4); + ASM_MOV_REG_REG(emit->as, REG_LOCAL_LAST, REG_PARENT_ARG_4); #endif // Check number of args matches this function, and call mp_arg_check_num_sig if not @@ -514,21 +528,21 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop // Store arguments into locals (reg or stack), converting to native if needed for (int i = 0; i < emit->scope->num_pos_args; i++) { int r = REG_ARG_1; - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_LOCAL_3, i); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_LOCAL_LAST, i); if (emit->local_vtype[i] != VTYPE_PYOBJ) { emit_call_with_imm_arg(emit, MP_F_CONVERT_OBJ_TO_NATIVE, emit->local_vtype[i], REG_ARG_2); r = REG_RET; } - // REG_LOCAL_3 points to the args array so be sure not to overwrite it if it's still needed - if (i < REG_LOCAL_NUM && CAN_USE_REGS_FOR_LOCALS(emit) && (i != 2 || emit->scope->num_pos_args == 3)) { + // REG_LOCAL_LAST points to the args array so be sure not to overwrite it if it's still needed + if (i < MAX_REGS_FOR_LOCAL_VARS && CAN_USE_REGS_FOR_LOCALS(emit) && (i != MAX_REGS_FOR_LOCAL_VARS - 1 || emit->scope->num_pos_args == MAX_REGS_FOR_LOCAL_VARS)) { ASM_MOV_REG_REG(emit->as, reg_local_table[i], r); } else { emit_native_mov_state_reg(emit, LOCAL_IDX_LOCAL_VAR(emit, i), r); } } - // Get 3rd local from the stack back into REG_LOCAL_3 if this reg couldn't be written to above - if (emit->scope->num_pos_args >= 4 && CAN_USE_REGS_FOR_LOCALS(emit)) { - ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_3, LOCAL_IDX_LOCAL_VAR(emit, 2)); + // Get local from the stack back into REG_LOCAL_LAST if this reg couldn't be written to above + if (emit->scope->num_pos_args >= MAX_REGS_FOR_LOCAL_VARS + 1 && CAN_USE_REGS_FOR_LOCALS(emit)) { + ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_LAST, LOCAL_IDX_LOCAL_VAR(emit, MAX_REGS_FOR_LOCAL_VARS - 1)); } emit_native_global_exc_entry(emit); @@ -538,16 +552,13 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop emit->n_state = scope->num_locals + scope->stack_size; if (emit->scope->scope_flags & MP_SCOPE_FLAG_GENERATOR) { + mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)emit->prelude_ptr_index); + mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)emit->start_offset); + ASM_ENTRY(emit->as, emit->code_state_start); + + // Reset the state size for the state pointed to by REG_GENERATOR_STATE emit->code_state_start = 0; emit->stack_start = SIZEOF_CODE_STATE; - #if N_PRELUDE_AS_BYTES_OBJ - // Load index of prelude bytes object in const_table - mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)(emit->scope->num_pos_args + emit->scope->num_kwonly_args + 1)); - #else - mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)emit->prelude_offset); - #endif - mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)emit->start_offset); - ASM_ENTRY(emit->as, SIZEOF_NLR_BUF); // Put address of code_state into REG_GENERATOR_STATE #if N_X86 @@ -564,8 +575,12 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_GENERATOR_STATE, LOCAL_IDX_FUN_OBJ(emit)); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_TEMP0, OFFSETOF_OBJ_FUN_BC_CONST_TABLE); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_TEMP0, emit->scope->num_pos_args + emit->scope->num_kwonly_args); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_TEMP0, OFFSETOF_OBJ_FUN_BC_CONTEXT); + #if MICROPY_PERSISTENT_CODE_SAVE + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_QSTR_TABLE, REG_TEMP0, OFFSETOF_MODULE_CONTEXT_QSTR_TABLE); + #endif + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_TEMP0, OFFSETOF_MODULE_CONTEXT_OBJ_TABLE); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_TEMP0, fun_table_off); } else { // The locals and stack start after the code_state structure emit->stack_start = emit->code_state_start + SIZEOF_CODE_STATE; @@ -583,38 +598,27 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop #endif // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_LOCAL_3, REG_PARENT_ARG_1, OFFSETOF_OBJ_FUN_BC_CONST_TABLE); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_LOCAL_3, emit->scope->num_pos_args + emit->scope->num_kwonly_args); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_PARENT_ARG_1, OFFSETOF_OBJ_FUN_BC_CONTEXT); + #if MICROPY_PERSISTENT_CODE_SAVE + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_QSTR_TABLE, REG_FUN_TABLE, OFFSETOF_MODULE_CONTEXT_QSTR_TABLE); + #endif + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_FUN_TABLE, OFFSETOF_MODULE_CONTEXT_OBJ_TABLE); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_FUN_TABLE, fun_table_off); // Set code_state.fun_bc ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_FUN_OBJ(emit), REG_PARENT_ARG_1); - // Set code_state.ip (offset from start of this function to prelude info) - int code_state_ip_local = emit->code_state_start + OFFSETOF_CODE_STATE_IP; - #if N_PRELUDE_AS_BYTES_OBJ - // Prelude is a bytes object in const_table; store ip = prelude->data - fun_bc->bytecode - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_LOCAL_3, REG_LOCAL_3, emit->scope->num_pos_args + emit->scope->num_kwonly_args + 1); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_LOCAL_3, REG_LOCAL_3, offsetof(mp_obj_str_t, data) / sizeof(uintptr_t)); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_PARENT_ARG_1, REG_PARENT_ARG_1, OFFSETOF_OBJ_FUN_BC_BYTECODE); - ASM_SUB_REG_REG(emit->as, REG_LOCAL_3, REG_PARENT_ARG_1); - emit_native_mov_state_reg(emit, code_state_ip_local, REG_LOCAL_3); - #else - if (emit->pass == MP_PASS_CODE_SIZE) { - // Commit to the encoding size based on the value of prelude_offset in this pass. - // By using 32768 as the cut-off it is highly unlikely that prelude_offset will - // grow beyond 65535 by the end of thiss pass, and so require the larger encoding. - emit->prelude_offset_uses_u16_encoding = emit->prelude_offset < 32768; + // Set code_state.ip, a pointer to the beginning of the prelude. This pointer is found + // either directly in mp_obj_fun_bc_t.child_table (if there are no children), or in + // mp_obj_fun_bc_t.child_table[num_children] (if num_children > 0). + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_PARENT_ARG_1, REG_PARENT_ARG_1, OFFSETOF_OBJ_FUN_BC_CHILD_TABLE); + if (emit->prelude_ptr_index != 0) { + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_PARENT_ARG_1, REG_PARENT_ARG_1, emit->prelude_ptr_index); } - if (emit->prelude_offset_uses_u16_encoding) { - assert(emit->prelude_offset <= 65535); - emit_native_mov_state_imm_fix_u16_via(emit, code_state_ip_local, emit->prelude_offset, REG_PARENT_ARG_1); - } else { - emit_native_mov_state_imm_fix_word_via(emit, code_state_ip_local, emit->prelude_offset, REG_PARENT_ARG_1); - } - #endif + emit_native_mov_state_reg(emit, emit->code_state_start + OFFSETOF_CODE_STATE_IP, REG_PARENT_ARG_1); // Set code_state.n_state (only works on little endian targets due to n_state being uint16_t) - emit_native_mov_state_imm_via(emit, emit->code_state_start + offsetof(mp_code_state_t, n_state) / sizeof(uintptr_t), emit->n_state, REG_ARG_1); + emit_native_mov_state_imm_via(emit, emit->code_state_start + OFFSETOF_CODE_STATE_N_STATE, emit->n_state, REG_ARG_1); // Put address of code_state into first arg ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, emit->code_state_start); @@ -644,7 +648,7 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop // cache some locals in registers, but only if no exception handlers if (CAN_USE_REGS_FOR_LOCALS(emit)) { - for (int i = 0; i < REG_LOCAL_NUM && i < scope->num_locals; ++i) { + for (int i = 0; i < MAX_REGS_FOR_LOCAL_VARS && i < scope->num_locals; ++i) { ASM_MOV_REG_LOCAL(emit->as, reg_local_table[i], LOCAL_IDX_LOCAL_VAR(emit, i)); } } @@ -656,55 +660,47 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop emit->local_vtype[id->local_num] = VTYPE_PYOBJ; } } - - if (pass == MP_PASS_EMIT) { - // write argument names as qstr objects - // see comment in corresponding part of emitbc.c about the logic here - for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) { - qstr qst = MP_QSTR__star_; - for (int j = 0; j < scope->id_info_len; ++j) { - id_info_t *id = &scope->id_info[j]; - if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) { - qst = id->qst; - break; - } - } - emit->const_table[i] = (mp_uint_t)MP_OBJ_NEW_QSTR(qst); - } - } } - } static inline void emit_native_write_code_info_byte(emit_t *emit, byte val) { mp_asm_base_data(&emit->as->base, 1, val); } -STATIC void emit_native_end_pass(emit_t *emit) { +static inline void emit_native_write_code_info_qstr(emit_t *emit, qstr qst) { + mp_encode_uint(&emit->as->base, mp_asm_base_get_cur_to_write_bytes, mp_emit_common_use_qstr(emit->emit_common, qst)); +} + +STATIC bool emit_native_end_pass(emit_t *emit) { emit_native_global_exc_exit(emit); if (!emit->do_viper_types) { emit->prelude_offset = mp_asm_base_get_code_pos(&emit->as->base); + emit->prelude_ptr_index = emit->emit_common->ct_cur_child; size_t n_state = emit->n_state; size_t n_exc_stack = 0; // exc-stack not needed for native code MP_BC_PRELUDE_SIG_ENCODE(n_state, n_exc_stack, emit->scope, emit_native_write_code_info_byte, emit); - #if MICROPY_PERSISTENT_CODE - size_t n_info = 4; - #else - size_t n_info = 1; - #endif - MP_BC_PRELUDE_SIZE_ENCODE(n_info, emit->n_cell, emit_native_write_code_info_byte, emit); - - #if MICROPY_PERSISTENT_CODE - mp_asm_base_data(&emit->as->base, 1, emit->scope->simple_name); - mp_asm_base_data(&emit->as->base, 1, emit->scope->simple_name >> 8); - mp_asm_base_data(&emit->as->base, 1, emit->scope->source_file); - mp_asm_base_data(&emit->as->base, 1, emit->scope->source_file >> 8); - #else - mp_asm_base_data(&emit->as->base, 1, 1); - #endif + size_t n_info = emit->n_info; + size_t n_cell = emit->n_cell; + MP_BC_PRELUDE_SIZE_ENCODE(n_info, n_cell, emit_native_write_code_info_byte, emit); + + // bytecode prelude: source info (function and argument qstrs) + size_t info_start = mp_asm_base_get_code_pos(&emit->as->base); + emit_native_write_code_info_qstr(emit, emit->scope->simple_name); + for (int i = 0; i < emit->scope->num_pos_args + emit->scope->num_kwonly_args; i++) { + qstr qst = MP_QSTR__star_; + for (int j = 0; j < emit->scope->id_info_len; ++j) { + id_info_t *id = &emit->scope->id_info[j]; + if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) { + qst = id->qst; + break; + } + } + emit_native_write_code_info_qstr(emit, qst); + } + emit->n_info = mp_asm_base_get_code_pos(&emit->as->base) - info_start; // bytecode prelude: initialise closed over variables size_t cell_start = mp_asm_base_get_code_pos(&emit->as->base); @@ -717,15 +713,6 @@ STATIC void emit_native_end_pass(emit_t *emit) { } emit->n_cell = mp_asm_base_get_code_pos(&emit->as->base) - cell_start; - #if N_PRELUDE_AS_BYTES_OBJ - // Prelude bytes object is after qstr arg names and mp_fun_table - size_t table_off = emit->scope->num_pos_args + emit->scope->num_kwonly_args + 1; - if (emit->pass == MP_PASS_EMIT) { - void *buf = emit->as->base.code_base + emit->prelude_offset; - size_t n = emit->as->base.code_offset - emit->prelude_offset; - emit->const_table[table_off] = (uintptr_t)mp_obj_new_bytes(buf, n); - } - #endif } ASM_END_PASS(emit->as); @@ -734,46 +721,45 @@ STATIC void emit_native_end_pass(emit_t *emit) { assert(emit->stack_size == 0); assert(emit->exc_stack_size == 0); - // Deal with const table accounting - assert(emit->pass <= MP_PASS_STACK_SIZE || (emit->const_table_num_obj == emit->const_table_cur_obj)); - emit->const_table_num_obj = emit->const_table_cur_obj; - if (emit->pass == MP_PASS_CODE_SIZE) { - size_t const_table_alloc = 1 + emit->const_table_num_obj + emit->const_table_cur_raw_code; - size_t nqstr = 0; - if (!emit->do_viper_types) { - // Add room for qstr names of arguments - nqstr = emit->scope->num_pos_args + emit->scope->num_kwonly_args; - const_table_alloc += nqstr; - } - emit->const_table = m_new(mp_uint_t, const_table_alloc); - #if !MICROPY_DYNAMIC_COMPILER - // Store mp_fun_table pointer just after qstrs - // (but in dynamic-compiler mode eliminate dependency on mp_fun_table) - emit->const_table[nqstr] = (mp_uint_t)(uintptr_t)&mp_fun_table; - #endif - - #if MICROPY_PERSISTENT_CODE_SAVE - size_t qstr_link_alloc = emit->qstr_link_cur; - if (qstr_link_alloc > 0) { - emit->qstr_link = m_new(mp_qstr_link_entry_t, qstr_link_alloc); - } - #endif - } - if (emit->pass == MP_PASS_EMIT) { void *f = mp_asm_base_get_code(&emit->as->base); mp_uint_t f_len = mp_asm_base_get_code_size(&emit->as->base); + mp_raw_code_t **children = emit->emit_common->children; + if (!emit->do_viper_types) { + #if MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE + // Executable code cannot be accessed byte-wise on this architecture, so copy + // the prelude to a separate memory region that is byte-wise readable. + void *buf = emit->as->base.code_base + emit->prelude_offset; + size_t n = emit->as->base.code_offset - emit->prelude_offset; + const uint8_t *prelude_ptr = memcpy(m_new(uint8_t, n), buf, n); + #else + // Point to the prelude directly, at the end of the machine code data. + const uint8_t *prelude_ptr = (const uint8_t *)f + emit->prelude_offset; + #endif + + // Store the pointer to the prelude using the child_table. + assert(emit->prelude_ptr_index == emit->emit_common->ct_cur_child); + if (emit->prelude_ptr_index == 0) { + children = (void *)prelude_ptr; + } else { + children = m_renew(mp_raw_code_t *, children, emit->prelude_ptr_index, emit->prelude_ptr_index + 1); + children[emit->prelude_ptr_index] = (void *)prelude_ptr; + } + } + mp_emit_glue_assign_native(emit->scope->raw_code, emit->do_viper_types ? MP_CODE_NATIVE_VIPER : MP_CODE_NATIVE_PY, - f, f_len, emit->const_table, + f, f_len, + children, #if MICROPY_PERSISTENT_CODE_SAVE + emit->emit_common->ct_cur_child, emit->prelude_offset, - emit->const_table_cur_obj, emit->const_table_cur_raw_code, - emit->qstr_link_cur, emit->qstr_link, #endif - emit->scope->num_pos_args, emit->scope->scope_flags, 0); + emit->scope->scope_flags, 0, 0); } + + return true; } STATIC bool emit_native_last_emit_was_return_value(emit_t *emit) { @@ -1165,29 +1151,20 @@ STATIC exc_stack_entry_t *emit_native_pop_exc_stack(emit_t *emit) { return e; } -STATIC void emit_load_reg_with_ptr(emit_t *emit, int reg, mp_uint_t ptr, size_t table_off) { - if (!emit->do_viper_types) { - // Skip qstr names of arguments - table_off += emit->scope->num_pos_args + emit->scope->num_kwonly_args; - } - if (emit->pass == MP_PASS_EMIT) { - emit->const_table[table_off] = ptr; - } +STATIC void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj) { + emit->scope->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; + size_t table_off = mp_emit_common_use_const_obj(emit->emit_common, obj); emit_native_mov_reg_state(emit, REG_TEMP0, LOCAL_IDX_FUN_OBJ(emit)); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_TEMP0, OFFSETOF_OBJ_FUN_BC_CONST_TABLE); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_TEMP0, OFFSETOF_OBJ_FUN_BC_CONTEXT); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_TEMP0, OFFSETOF_MODULE_CONTEXT_OBJ_TABLE); ASM_LOAD_REG_REG_OFFSET(emit->as, reg, REG_TEMP0, table_off); } -STATIC void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj) { - // First entry is for mp_fun_table - size_t table_off = 1 + emit->const_table_cur_obj++; - emit_load_reg_with_ptr(emit, reg, (mp_uint_t)obj, table_off); -} - -STATIC void emit_load_reg_with_raw_code(emit_t *emit, int reg, mp_raw_code_t *rc) { - // First entry is for mp_fun_table, then constant objects - size_t table_off = 1 + emit->const_table_num_obj + emit->const_table_cur_raw_code++; - emit_load_reg_with_ptr(emit, reg, (mp_uint_t)rc, table_off); +STATIC void emit_load_reg_with_child(emit_t *emit, int reg, mp_raw_code_t *rc) { + size_t table_off = mp_emit_common_alloc_const_child(emit->emit_common, rc); + emit_native_mov_reg_state(emit, REG_TEMP0, LOCAL_IDX_FUN_OBJ(emit)); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_TEMP0, OFFSETOF_OBJ_FUN_BC_CHILD_TABLE); + ASM_LOAD_REG_REG_OFFSET(emit->as, reg, REG_TEMP0, table_off); } STATIC void emit_native_label_assign(emit_t *emit, mp_uint_t l) { @@ -1231,7 +1208,8 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) { if (!(emit->scope->scope_flags & MP_SCOPE_FLAG_GENERATOR)) { // Set new globals emit_native_mov_reg_state(emit, REG_ARG_1, LOCAL_IDX_FUN_OBJ(emit)); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_ARG_1, OFFSETOF_OBJ_FUN_BC_GLOBALS); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_ARG_1, OFFSETOF_OBJ_FUN_BC_CONTEXT); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_ARG_1, OFFSETOF_MODULE_CONTEXT_GLOBALS); emit_call(emit, MP_F_NATIVE_SWAP_GLOBALS); // Save old globals (or NULL if globals didn't change) @@ -1262,14 +1240,12 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) { // Wrap everything in an nlr context emit_native_label_assign(emit, nlr_label); - ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_2, LOCAL_IDX_EXC_HANDLER_UNWIND(emit)); ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 0); emit_call(emit, MP_F_NLR_PUSH); #if N_NLR_SETJMP ASM_MOV_REG_LOCAL_ADDR(emit->as, REG_ARG_1, 2); emit_call(emit, MP_F_SETJMP); #endif - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_LOCAL_2); ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, global_except_label, true); // Clear PC of current code block, and jump there to resume execution @@ -1279,12 +1255,6 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) { // Global exception handler: check for valid exception handler emit_native_label_assign(emit, global_except_label); - #if N_NLR_SETJMP - // Reload REG_FUN_TABLE, since it may be clobbered by longjmp - emit_native_mov_reg_state(emit, REG_LOCAL_1, LOCAL_IDX_FUN_OBJ(emit)); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_LOCAL_1, REG_LOCAL_1, offsetof(mp_obj_fun_bc_t, const_table) / sizeof(uintptr_t)); - ASM_LOAD_REG_REG_OFFSET(emit->as, REG_FUN_TABLE, REG_LOCAL_1, emit->scope->num_pos_args + emit->scope->num_kwonly_args); - #endif ASM_MOV_REG_LOCAL(emit->as, REG_LOCAL_1, LOCAL_IDX_EXC_HANDLER_PC(emit)); ASM_JUMP_IF_REG_NONZERO(emit->as, REG_LOCAL_1, nlr_label, false); } @@ -1413,11 +1383,7 @@ STATIC void emit_native_import(emit_t *emit, qstr qst, int kind) { STATIC void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) { DEBUG_printf("load_const_tok(tok=%u)\n", tok); if (tok == MP_TOKEN_ELLIPSIS) { - #if MICROPY_PERSISTENT_CODE_SAVE emit_native_load_const_obj(emit, MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj)); - #else - emit_post_push_imm(emit, VTYPE_PYOBJ, (mp_uint_t)MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj)); - #endif } else { emit_native_pre(emit); if (tok == MP_TOKEN_KW_NONE) { @@ -1452,7 +1418,6 @@ STATIC void emit_native_load_const_str(emit_t *emit, qstr qst) { } STATIC void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj) { - emit->scope->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; emit_native_pre(emit); need_reg_single(emit, REG_RET, 0); emit_load_reg_with_object(emit, REG_RET, obj); @@ -1471,7 +1436,7 @@ STATIC void emit_native_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) { EMIT_NATIVE_VIPER_TYPE_ERROR(emit, MP_ERROR_TEXT("local '%q' used before type known"), qst); } emit_native_pre(emit); - if (local_num < REG_LOCAL_NUM && CAN_USE_REGS_FOR_LOCALS(emit)) { + if (local_num < MAX_REGS_FOR_LOCAL_VARS && CAN_USE_REGS_FOR_LOCALS(emit)) { emit_post_push_reg(emit, vtype, reg_local_table[local_num]); } else { need_reg_single(emit, REG_TEMP0, 0); @@ -1692,7 +1657,7 @@ STATIC void emit_native_load_subscr(emit_t *emit) { STATIC void emit_native_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num) { vtype_kind_t vtype; - if (local_num < REG_LOCAL_NUM && CAN_USE_REGS_FOR_LOCALS(emit)) { + if (local_num < MAX_REGS_FOR_LOCAL_VARS && CAN_USE_REGS_FOR_LOCALS(emit)) { emit_pre_pop_reg(emit, &vtype, reg_local_table[local_num]); } else { emit_pre_pop_reg(emit, &vtype, REG_TEMP0); @@ -2485,48 +2450,48 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { asm_x86_setcc_r8(emit->as, ops[op_idx], REG_RET); #elif N_THUMB asm_thumb_cmp_rlo_rlo(emit->as, REG_ARG_2, reg_rhs); - #if MICROPY_EMIT_THUMB_ARMV7M - static uint16_t ops[6 + 6] = { - // unsigned - ASM_THUMB_OP_ITE_CC, - ASM_THUMB_OP_ITE_HI, - ASM_THUMB_OP_ITE_EQ, - ASM_THUMB_OP_ITE_LS, - ASM_THUMB_OP_ITE_CS, - ASM_THUMB_OP_ITE_NE, - // signed - ASM_THUMB_OP_ITE_LT, - ASM_THUMB_OP_ITE_GT, - ASM_THUMB_OP_ITE_EQ, - ASM_THUMB_OP_ITE_LE, - ASM_THUMB_OP_ITE_GE, - ASM_THUMB_OP_ITE_NE, - }; - asm_thumb_op16(emit->as, ops[op_idx]); - asm_thumb_mov_rlo_i8(emit->as, REG_RET, 1); - asm_thumb_mov_rlo_i8(emit->as, REG_RET, 0); - #else - static uint16_t ops[6 + 6] = { - // unsigned - ASM_THUMB_CC_CC, - ASM_THUMB_CC_HI, - ASM_THUMB_CC_EQ, - ASM_THUMB_CC_LS, - ASM_THUMB_CC_CS, - ASM_THUMB_CC_NE, - // signed - ASM_THUMB_CC_LT, - ASM_THUMB_CC_GT, - ASM_THUMB_CC_EQ, - ASM_THUMB_CC_LE, - ASM_THUMB_CC_GE, - ASM_THUMB_CC_NE, - }; - asm_thumb_bcc_rel9(emit->as, ops[op_idx], 6); - asm_thumb_mov_rlo_i8(emit->as, REG_RET, 0); - asm_thumb_b_rel12(emit->as, 4); - asm_thumb_mov_rlo_i8(emit->as, REG_RET, 1); - #endif + if (asm_thumb_allow_armv7m(emit->as)) { + static uint16_t ops[6 + 6] = { + // unsigned + ASM_THUMB_OP_ITE_CC, + ASM_THUMB_OP_ITE_HI, + ASM_THUMB_OP_ITE_EQ, + ASM_THUMB_OP_ITE_LS, + ASM_THUMB_OP_ITE_CS, + ASM_THUMB_OP_ITE_NE, + // signed + ASM_THUMB_OP_ITE_LT, + ASM_THUMB_OP_ITE_GT, + ASM_THUMB_OP_ITE_EQ, + ASM_THUMB_OP_ITE_LE, + ASM_THUMB_OP_ITE_GE, + ASM_THUMB_OP_ITE_NE, + }; + asm_thumb_op16(emit->as, ops[op_idx]); + asm_thumb_mov_rlo_i8(emit->as, REG_RET, 1); + asm_thumb_mov_rlo_i8(emit->as, REG_RET, 0); + } else { + static uint16_t ops[6 + 6] = { + // unsigned + ASM_THUMB_CC_CC, + ASM_THUMB_CC_HI, + ASM_THUMB_CC_EQ, + ASM_THUMB_CC_LS, + ASM_THUMB_CC_CS, + ASM_THUMB_CC_NE, + // signed + ASM_THUMB_CC_LT, + ASM_THUMB_CC_GT, + ASM_THUMB_CC_EQ, + ASM_THUMB_CC_LE, + ASM_THUMB_CC_GE, + ASM_THUMB_CC_NE, + }; + asm_thumb_bcc_rel9(emit->as, ops[op_idx], 6); + asm_thumb_mov_rlo_i8(emit->as, REG_RET, 0); + asm_thumb_b_rel12(emit->as, 4); + asm_thumb_mov_rlo_i8(emit->as, REG_RET, 1); + } #elif N_ARM asm_arm_cmp_reg_reg(emit->as, REG_ARG_2, reg_rhs); static uint ccs[6 + 6] = { @@ -2710,33 +2675,46 @@ STATIC void emit_native_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_ri STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) { // call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them emit_native_pre(emit); + emit_native_mov_reg_state(emit, REG_ARG_2, LOCAL_IDX_FUN_OBJ(emit)); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_2, REG_ARG_2, OFFSETOF_OBJ_FUN_BC_CONTEXT); if (n_pos_defaults == 0 && n_kw_defaults == 0) { need_reg_all(emit); - ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL); - ASM_MOV_REG_IMM(emit->as, REG_ARG_3, (mp_uint_t)MP_OBJ_NULL); + ASM_MOV_REG_IMM(emit->as, REG_ARG_3, 0); } else { - vtype_kind_t vtype_def_tuple, vtype_def_dict; - emit_pre_pop_reg_reg(emit, &vtype_def_dict, REG_ARG_3, &vtype_def_tuple, REG_ARG_2); - assert(vtype_def_tuple == VTYPE_PYOBJ); - assert(vtype_def_dict == VTYPE_PYOBJ); + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 2); need_reg_all(emit); } - emit_load_reg_with_raw_code(emit, REG_ARG_1, scope->raw_code); + emit_load_reg_with_child(emit, REG_ARG_1, scope->raw_code); ASM_CALL_IND(emit->as, MP_F_MAKE_FUNCTION_FROM_RAW_CODE); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } STATIC void emit_native_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) { + // make function emit_native_pre(emit); + emit_native_mov_reg_state(emit, REG_ARG_2, LOCAL_IDX_FUN_OBJ(emit)); + ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_2, REG_ARG_2, OFFSETOF_OBJ_FUN_BC_CONTEXT); if (n_pos_defaults == 0 && n_kw_defaults == 0) { - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over); - ASM_MOV_REG_IMM(emit->as, REG_ARG_2, n_closed_over); + need_reg_all(emit); + ASM_MOV_REG_IMM(emit->as, REG_ARG_3, 0); } else { - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over + 2); - ASM_MOV_REG_IMM(emit->as, REG_ARG_2, 0x100 | n_closed_over); + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 2 + n_closed_over); + adjust_stack(emit, 2 + n_closed_over); + need_reg_all(emit); + } + emit_load_reg_with_child(emit, REG_ARG_1, scope->raw_code); + ASM_CALL_IND(emit->as, MP_F_MAKE_FUNCTION_FROM_RAW_CODE); + + // make closure + #if REG_ARG_1 != REG_RET + ASM_MOV_REG_REG(emit->as, REG_ARG_1, REG_RET); + #endif + ASM_MOV_REG_IMM(emit->as, REG_ARG_2, n_closed_over); + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_closed_over); + if (n_pos_defaults != 0 || n_kw_defaults != 0) { + adjust_stack(emit, -2); } - emit_load_reg_with_raw_code(emit, REG_ARG_1, scope->raw_code); - ASM_CALL_IND(emit->as, MP_F_MAKE_CLOSURE_FROM_RAW_CODE); + ASM_CALL_IND(emit->as, MP_F_NEW_CLOSURE); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } @@ -2781,7 +2759,7 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u } else { assert(vtype_fun == VTYPE_PYOBJ); if (star_flags) { - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 3); // pointer to args + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 2); // pointer to args emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW_VAR, 0, REG_ARG_1, n_positional | (n_keyword << 8), REG_ARG_2); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } else { @@ -2797,7 +2775,7 @@ STATIC void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u STATIC void emit_native_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) { if (star_flags) { - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 4); // pointer to args + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 3); // pointer to args emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW_VAR, 1, REG_ARG_1, n_positional | (n_keyword << 8), REG_ARG_2); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } else { diff --git a/py/emitnthumb.c b/py/emitnthumb.c index 1c33e7a68b59e..844a73ffa8c92 100644 --- a/py/emitnthumb.c +++ b/py/emitnthumb.c @@ -10,8 +10,6 @@ // Word indices of REG_LOCAL_x in nlr_buf_t #define NLR_BUF_IDX_LOCAL_1 (3) // r4 -#define NLR_BUF_IDX_LOCAL_2 (4) // r5 -#define NLR_BUF_IDX_LOCAL_3 (5) // r6 #define N_THUMB (1) #define EXPORT_FUN(name) emit_native_thumb_##name diff --git a/py/emitnx64.c b/py/emitnx64.c index 4abb3ecad3a32..1b32286d27be9 100644 --- a/py/emitnx64.c +++ b/py/emitnx64.c @@ -10,8 +10,6 @@ // Word indices of REG_LOCAL_x in nlr_buf_t #define NLR_BUF_IDX_LOCAL_1 (5) // rbx -#define NLR_BUF_IDX_LOCAL_2 (6) // r12 -#define NLR_BUF_IDX_LOCAL_3 (7) // r13 #define N_X64 (1) #define EXPORT_FUN(name) emit_native_x64_##name diff --git a/py/emitnx86.c b/py/emitnx86.c index f0553f0682bb9..a9050c65d4036 100644 --- a/py/emitnx86.c +++ b/py/emitnx86.c @@ -11,8 +11,6 @@ // Word indices of REG_LOCAL_x in nlr_buf_t #define NLR_BUF_IDX_LOCAL_1 (5) // ebx -#define NLR_BUF_IDX_LOCAL_2 (7) // esi -#define NLR_BUF_IDX_LOCAL_3 (6) // edi // x86 needs a table to know how many args a given function has STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { @@ -56,7 +54,7 @@ STATIC byte mp_f_n_args[MP_F_NUMBER_OF] = { [MP_F_UNPACK_EX] = 3, [MP_F_DELETE_NAME] = 1, [MP_F_DELETE_GLOBAL] = 1, - [MP_F_MAKE_CLOSURE_FROM_RAW_CODE] = 3, + [MP_F_NEW_CLOSURE] = 3, [MP_F_ARG_CHECK_NUM_SIG] = 3, [MP_F_SETUP_CODE_STATE] = 4, [MP_F_SMALL_INT_FLOOR_DIVIDE] = 2, diff --git a/py/emitnxtensa.c b/py/emitnxtensa.c index 34089e90dc27b..c89b029023028 100644 --- a/py/emitnxtensa.c +++ b/py/emitnxtensa.c @@ -10,8 +10,6 @@ // Word indices of REG_LOCAL_x in nlr_buf_t #define NLR_BUF_IDX_LOCAL_1 (8) // a12 -#define NLR_BUF_IDX_LOCAL_2 (9) // a13 -#define NLR_BUF_IDX_LOCAL_3 (10) // a14 #define N_XTENSA (1) #define EXPORT_FUN(name) emit_native_xtensa_##name diff --git a/py/emitnxtensawin.c b/py/emitnxtensawin.c index 38d5db13ea450..f6eeff8455b97 100644 --- a/py/emitnxtensawin.c +++ b/py/emitnxtensawin.c @@ -11,11 +11,8 @@ // Word indices of REG_LOCAL_x in nlr_buf_t #define NLR_BUF_IDX_LOCAL_1 (2 + 4) // a4 -#define NLR_BUF_IDX_LOCAL_2 (2 + 5) // a5 -#define NLR_BUF_IDX_LOCAL_3 (2 + 6) // a6 #define N_NLR_SETJMP (1) -#define N_PRELUDE_AS_BYTES_OBJ (1) #define N_XTENSAWIN (1) #define EXPORT_FUN(name) emit_native_xtensawin_##name #include "py/emitnative.c" diff --git a/py/formatfloat.c b/py/formatfloat.c index 4671f3348bcf1..854944976f0cc 100644 --- a/py/formatfloat.c +++ b/py/formatfloat.c @@ -1,9 +1,11 @@ +// CIRCUITPY: https://github.com/adafruit/circuitpython/pull/6722 +// post v1.19.1. Remove this comment during v1.20 merge. /* * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/formatfloat.h b/py/formatfloat.h index c433cb8057a41..9a1643b4ddff5 100644 --- a/py/formatfloat.h +++ b/py/formatfloat.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/frozenmod.c b/py/frozenmod.c index 57e9d5df9b99a..61c2f20aa1de3 100644 --- a/py/frozenmod.c +++ b/py/frozenmod.c @@ -4,8 +4,8 @@ * The MIT License (MIT) * * Copyright (c) 2015 Paul Sokolovsky - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2021 Jim Mussared + * Copyright (c) 2016 Damien P. George + * Copyright (c) 2021 Jim Mussared * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -57,7 +57,7 @@ extern const char mp_frozen_str_content[]; #include "py/emitglue.h" -extern const mp_raw_code_t *const mp_frozen_mpy_content[]; +extern const mp_frozen_module_t *const mp_frozen_mpy_content[]; #endif // MICROPY_MODULE_FROZEN_MPY diff --git a/py/frozenmod.h b/py/frozenmod.h index 0a907b8785b2d..cff6c8616c755 100644 --- a/py/frozenmod.h +++ b/py/frozenmod.h @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2015 Paul Sokolovsky - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2015 Paul Sokolovsky + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_PY_FROZENMOD_H #define MICROPY_INCLUDED_PY_FROZENMOD_H -#include "py/lexer.h" +#include "py/builtin.h" enum { MP_FROZEN_NONE, diff --git a/py/gc.c b/py/gc.c index d723272f04ac5..d83fe2dfa8300 100644 --- a/py/gc.c +++ b/py/gc.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,6 +62,9 @@ // detect untraced object still in use #define CLEAR_ON_SWEEP (0) +#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / MP_BYTES_PER_OBJ_WORD) +#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK) + // ATB = allocation table byte // 0b00 = FREE -- free block // 0b01 = HEAD -- head of a chain of blocks @@ -74,6 +77,15 @@ #define AT_MARK (3) #define BLOCKS_PER_ATB (4) +#define ATB_MASK_0 (0x03) +#define ATB_MASK_1 (0x0c) +#define ATB_MASK_2 (0x30) +#define ATB_MASK_3 (0xc0) + +#define ATB_0_IS_FREE(a) (((a) & ATB_MASK_0) == 0) +#define ATB_1_IS_FREE(a) (((a) & ATB_MASK_1) == 0) +#define ATB_2_IS_FREE(a) (((a) & ATB_MASK_2) == 0) +#define ATB_3_IS_FREE(a) (((a) & ATB_MASK_3) == 0) #define BLOCK_SHIFT(block) (2 * ((block) & (BLOCKS_PER_ATB - 1))) #define ATB_GET_KIND(block) ((MP_STATE_MEM(gc_alloc_table_start)[(block) / BLOCKS_PER_ATB] >> BLOCK_SHIFT(block)) & 3) @@ -130,6 +142,7 @@ void gc_init(void *start, void *end) { // => T = A * (1 + BLOCKS_PER_ATB / BLOCKS_PER_FTB + BLOCKS_PER_ATB * BYTES_PER_BLOCK) size_t total_byte_len = (byte *)end - (byte *)start; #if MICROPY_ENABLE_FINALISER + // CIRCUITPY: https://github.com/adafruit/circuitpython/pull/5245 (bug fix) MP_STATE_MEM(gc_alloc_table_byte_len) = (total_byte_len - 1) * MP_BITS_PER_BYTE / (MP_BITS_PER_BYTE + MP_BITS_PER_BYTE * BLOCKS_PER_ATB / BLOCKS_PER_FTB + MP_BITS_PER_BYTE * BLOCKS_PER_ATB * BYTES_PER_BLOCK); #else MP_STATE_MEM(gc_alloc_table_byte_len) = total_byte_len / (1 + MP_BITS_PER_BYTE / 2 * BYTES_PER_BLOCK); @@ -138,7 +151,8 @@ void gc_init(void *start, void *end) { MP_STATE_MEM(gc_alloc_table_start) = (byte *)start; #if MICROPY_ENABLE_FINALISER - MP_STATE_MEM(gc_finaliser_table_start) = MP_STATE_MEM(gc_alloc_table_start) + MP_STATE_MEM(gc_alloc_table_byte_len) + 1; + size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB; + MP_STATE_MEM(gc_finaliser_table_start) = MP_STATE_MEM(gc_alloc_table_start) + MP_STATE_MEM(gc_alloc_table_byte_len); #endif size_t gc_pool_block_len = MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB; @@ -146,34 +160,27 @@ void gc_init(void *start, void *end) { MP_STATE_MEM(gc_pool_end) = end; #if MICROPY_ENABLE_FINALISER - size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB; + // CIRCUITPY: https://github.com/adafruit/circuitpython/pull/6397 (compiler diagnostic) (void)gc_finaliser_table_byte_len; // avoid unused variable diagnostic if asserts are disabled assert(MP_STATE_MEM(gc_pool_start) >= MP_STATE_MEM(gc_finaliser_table_start) + gc_finaliser_table_byte_len); #endif - // Clear ATBs & finalisers (if enabled). This also clears the extra byte - // which appears between ATBs and finalisers that ensures every chain in - // the ATB terminates, rather than erroneously using bits from the - // finalisers. - memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_pool_start) - MP_STATE_MEM(gc_alloc_table_start)); + // clear ATB's + memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_alloc_table_byte_len)); - // Set first free ATB index to the start of the heap. - for (size_t i = 0; i < MICROPY_ATB_INDICES; i++) { - MP_STATE_MEM(gc_first_free_atb_index)[i] = 0; - } - - // Set last free ATB index to the end of the heap. - MP_STATE_MEM(gc_last_free_atb_index) = MP_STATE_MEM(gc_alloc_table_byte_len) - 1; + #if MICROPY_ENABLE_FINALISER + // clear FTB's + memset(MP_STATE_MEM(gc_finaliser_table_start), 0, gc_finaliser_table_byte_len); + #endif - // Set the lowest long lived ptr to the end of the heap to start. This will be lowered as long - // lived objects are allocated. - MP_STATE_MEM(gc_lowest_long_lived_ptr) = (void *)PTR_FROM_BLOCK(MP_STATE_MEM(gc_alloc_table_byte_len * BLOCKS_PER_ATB)); + // set last free ATB index to start of heap + MP_STATE_MEM(gc_last_free_atb_index) = 0; // unlock the GC MP_STATE_THREAD(gc_lock_depth) = 0; // allow auto collection - MP_STATE_MEM(gc_auto_collect_enabled) = true; + MP_STATE_MEM(gc_auto_collect_enabled) = 1; #if MICROPY_GC_ALLOC_THRESHOLD // by default, maxuint for gc threshold, effectively turning gc-by-threshold off @@ -219,6 +226,8 @@ bool gc_is_locked(void) { return MP_STATE_THREAD(gc_lock_depth) != 0; } +// CIRCUITPY: VERIFY_PTR moved to gc.h to make it available elsewhere. + #ifndef TRACE_MARK #if DEBUG_PRINT #define TRACE_MARK(block, ptr) DEBUG_printf("gc_mark(%p)\n", ptr) @@ -231,7 +240,7 @@ bool gc_is_locked(void) { // children: mark the unmarked child blocks and put those newly marked // blocks on the stack. When all children have been checked, pop off the // topmost block on the stack and repeat with that one. -// We don't instrument these functions because they occur a lot during GC and +// CIRCUITPY: We don't instrument these functions because they occur a lot during GC and // fill up the output buffer quickly. STATIC void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark_subtree)(size_t block) { // Start with the block passed in the argument. @@ -412,6 +421,7 @@ void gc_collect_root(void **ptrs, size_t len) { for (size_t i = 0; i < len; i++) { MICROPY_GC_HOOK_LOOP void *ptr = gc_get_ptr(ptrs, i); + // CIRCUITPY changed in PR #1816 gc_mark(ptr); } } @@ -419,10 +429,7 @@ void gc_collect_root(void **ptrs, size_t len) { void gc_collect_end(void) { gc_deal_with_stack_overflow(); gc_sweep(); - for (size_t i = 0; i < MICROPY_ATB_INDICES; i++) { - MP_STATE_MEM(gc_first_free_atb_index)[i] = 0; - } - MP_STATE_MEM(gc_last_free_atb_index) = MP_STATE_MEM(gc_alloc_table_byte_len) - 1; + MP_STATE_MEM(gc_last_free_atb_index) = 0; MP_STATE_THREAD(gc_lock_depth)--; GC_EXIT(); } @@ -502,9 +509,7 @@ bool gc_alloc_possible(void) { return MP_STATE_MEM(gc_pool_start) != 0; } -// We place long lived objects at the end of the heap rather than the start. This reduces -// fragmentation by localizing the heap churn to one portion of memory (the start of the heap.) -void *gc_alloc(size_t n_bytes, unsigned int alloc_flags, bool long_lived) { +void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) { bool has_finaliser = alloc_flags & GC_ALLOC_FLAG_HAS_FINALISER; size_t n_blocks = ((n_bytes + BYTES_PER_BLOCK - 1) & (~(BYTES_PER_BLOCK - 1))) / BYTES_PER_BLOCK; DEBUG_printf("gc_alloc(" UINT_FMT " bytes -> " UINT_FMT " blocks)\n", n_bytes, n_blocks); @@ -525,11 +530,11 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags, bool long_lived) { GC_ENTER(); - size_t found_block = 0xffffffff; + size_t i; size_t end_block; size_t start_block; size_t n_free; - bool collected = !MP_STATE_MEM(gc_auto_collect_enabled); + int collected = !MP_STATE_MEM(gc_auto_collect_enabled); #if MICROPY_GC_ALLOC_THRESHOLD if (!collected && MP_STATE_MEM(gc_alloc_amount) >= MP_STATE_MEM(gc_alloc_threshold)) { @@ -540,49 +545,18 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags, bool long_lived) { } #endif - bool keep_looking = true; - - // When we start searching on the other side of the crossover block we make sure to - // perform a collect. That way we'll get the closest free block in our section. - size_t crossover_block = BLOCK_FROM_PTR(MP_STATE_MEM(gc_lowest_long_lived_ptr)); - while (keep_looking) { - int8_t direction = 1; - size_t bucket = MIN(n_blocks, MICROPY_ATB_INDICES) - 1; - size_t first_free = MP_STATE_MEM(gc_first_free_atb_index)[bucket]; - size_t start = first_free; - if (long_lived) { - direction = -1; - start = MP_STATE_MEM(gc_last_free_atb_index); - } - n_free = 0; + for (;;) { + // look for a run of n_blocks available blocks - for (size_t i = start; keep_looking && first_free <= i && i <= MP_STATE_MEM(gc_last_free_atb_index); i += direction) { + n_free = 0; + for (i = MP_STATE_MEM(gc_last_free_atb_index); i < MP_STATE_MEM(gc_alloc_table_byte_len); i++) { byte a = MP_STATE_MEM(gc_alloc_table_start)[i]; - // Four ATB states are packed into a single byte. - int j = 0; - if (direction == -1) { - j = 3; - } - for (; keep_looking && 0 <= j && j <= 3; j += direction) { - if ((a & (0x3 << (j * 2))) == 0) { - if (++n_free >= n_blocks) { - found_block = i * BLOCKS_PER_ATB + j; - keep_looking = false; - } - } else { - if (!collected) { - size_t block = i * BLOCKS_PER_ATB + j; - if ((direction == 1 && block >= crossover_block) || - (direction == -1 && block < crossover_block)) { - keep_looking = false; - } - } - n_free = 0; - } - } - } - if (n_free >= n_blocks) { - break; + // *FORMAT-OFF* + if (ATB_0_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 0; goto found; } } else { n_free = 0; } + if (ATB_1_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 1; goto found; } } else { n_free = 0; } + if (ATB_2_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 2; goto found; } } else { n_free = 0; } + if (ATB_3_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 3; goto found; } } else { n_free = 0; } + // *FORMAT-ON* } GC_EXIT(); @@ -592,35 +566,26 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags, bool long_lived) { } DEBUG_printf("gc_alloc(" UINT_FMT "): no free mem, triggering GC\n", n_bytes); gc_collect(); - collected = true; - // Try again since we've hopefully freed up space. - keep_looking = true; + collected = 1; GC_ENTER(); } - assert(found_block != 0xffffffff); - - // Found free space ending at found_block inclusive. - // Also, set last free ATB index to block after last block we found, for start of - // next scan. Also, whenever we free or shrink a block we must check if this index needs - // adjusting (see gc_realloc and gc_free). - if (!long_lived) { - end_block = found_block; - start_block = found_block - n_free + 1; - if (n_blocks < MICROPY_ATB_INDICES) { - size_t next_free_atb = (found_block + n_blocks) / BLOCKS_PER_ATB; - // Update all atb indices for larger blocks too. - for (size_t i = n_blocks - 1; i < MICROPY_ATB_INDICES; i++) { - MP_STATE_MEM(gc_first_free_atb_index)[i] = next_free_atb; - } - } - } else { - start_block = found_block; - end_block = found_block + n_free - 1; - // Always update the bounds of the long lived area because we assume it is contiguous. (It - // can still be reset by a sweep.) - MP_STATE_MEM(gc_last_free_atb_index) = (found_block - 1) / BLOCKS_PER_ATB; + + // found, ending at block i inclusive +found: + // get starting and end blocks, both inclusive + end_block = i; + start_block = i - n_free + 1; + + // Set last free ATB index to block after last block we found, for start of + // next scan. To reduce fragmentation, we only do this if we were looking + // for a single free block, which guarantees that there are no free blocks + // before this one. Also, whenever we free or shink a block we must check + // if this index needs adjusting (see gc_realloc and gc_free). + if (n_free == 1) { + MP_STATE_MEM(gc_last_free_atb_index) = (i + 1) / BLOCKS_PER_ATB; } + #ifdef LOG_HEAP_ACTIVITY gc_log_change(start_block, end_block - start_block + 1); #endif @@ -639,13 +604,6 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags, bool long_lived) { void *ret_ptr = (void *)(MP_STATE_MEM(gc_pool_start) + start_block * BYTES_PER_BLOCK); DEBUG_printf("gc_alloc(%p)\n", ret_ptr); - // If the allocation was long live then update the lowest value. Its used to trigger early - // collects when allocations fail in their respective section. Its also used to ignore calls to - // gc_make_long_lived where the pointer is already in the long lived section. - if (long_lived && ret_ptr < MP_STATE_MEM(gc_lowest_long_lived_ptr)) { - MP_STATE_MEM(gc_lowest_long_lived_ptr) = ret_ptr; - } - #if MICROPY_GC_ALLOC_THRESHOLD MP_STATE_MEM(gc_alloc_amount) += n_blocks; #endif @@ -713,42 +671,34 @@ void gc_free(void *ptr) { if (ptr == NULL) { GC_EXIT(); } else { + // CIRCUITPY extra checking if (MP_STATE_MEM(gc_pool_start) == 0) { reset_into_safe_mode(SAFE_MODE_GC_ALLOC_OUTSIDE_VM); } // get the GC block number corresponding to this pointer assert(VERIFY_PTR(ptr)); - size_t start_block = BLOCK_FROM_PTR(ptr); - assert(ATB_GET_KIND(start_block) == AT_HEAD); + size_t block = BLOCK_FROM_PTR(ptr); + assert(ATB_GET_KIND(block) == AT_HEAD); #if MICROPY_ENABLE_FINALISER - FTB_CLEAR(start_block); + FTB_CLEAR(block); #endif - // free head and all of its tail blocks + // set the last_free pointer to this block if it's earlier in the heap + if (block / BLOCKS_PER_ATB < MP_STATE_MEM(gc_last_free_atb_index)) { + MP_STATE_MEM(gc_last_free_atb_index) = block / BLOCKS_PER_ATB; + } + #ifdef LOG_HEAP_ACTIVITY gc_log_change(start_block, 0); #endif - size_t block = start_block; + + // free head and all of its tail blocks do { ATB_ANY_TO_FREE(block); block += 1; } while (ATB_GET_KIND(block) == AT_TAIL); - // Update the first free pointer for our size only. Not much calls gc_free directly so there - // is decent chance we'll want to allocate this size again. By only updating the specific - // size we don't risk something smaller fitting in. - size_t n_blocks = block - start_block; - size_t bucket = MIN(n_blocks, MICROPY_ATB_INDICES) - 1; - size_t new_free_atb = start_block / BLOCKS_PER_ATB; - if (new_free_atb < MP_STATE_MEM(gc_first_free_atb_index)[bucket]) { - MP_STATE_MEM(gc_first_free_atb_index)[bucket] = new_free_atb; - } - // set the last_free pointer to this block if it's earlier in the heap - if (new_free_atb > MP_STATE_MEM(gc_last_free_atb_index)) { - MP_STATE_MEM(gc_last_free_atb_index) = new_free_atb; - } - GC_EXIT(); #if EXTENSIVE_HEAP_PROFILING @@ -794,33 +744,6 @@ bool gc_has_finaliser(const void *ptr) { return false; } -void *gc_make_long_lived(void *old_ptr) { - // If its already in the long lived section then don't bother moving it. - if (old_ptr >= MP_STATE_MEM(gc_lowest_long_lived_ptr)) { - return old_ptr; - } - size_t n_bytes = gc_nbytes(old_ptr); - if (n_bytes == 0) { - return old_ptr; - } - bool has_finaliser = gc_has_finaliser(old_ptr); - - // Try and find a new area in the long lived section to copy the memory to. - void *new_ptr = gc_alloc(n_bytes, has_finaliser, true); - if (new_ptr == NULL) { - return old_ptr; - } else if (old_ptr > new_ptr) { - // Return the old pointer if the new one is lower in the heap and free the new space. - gc_free(new_ptr); - return old_ptr; - } - // We copy everything over and let the garbage collection process delete the old copy. That way - // we ensure we don't delete memory that has a second reference. (Though if there is we may - // confuse things when its mutable.) - memcpy(new_ptr, old_ptr, n_bytes); - return new_ptr; -} - #if 0 // old, simple realloc that didn't expand memory in place void *gc_realloc(void *ptr, mp_uint_t n_bytes) { @@ -853,7 +776,7 @@ void *gc_realloc(void *ptr, mp_uint_t n_bytes) { void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { // check for pure allocation if (ptr_in == NULL) { - return gc_alloc(n_bytes, false, false); + return gc_alloc(n_bytes, false); } // check for pure free @@ -918,13 +841,8 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { } // set the last_free pointer to end of this block if it's earlier in the heap - size_t new_free_atb = (block + new_blocks) / BLOCKS_PER_ATB; - size_t bucket = MIN(n_blocks - new_blocks, MICROPY_ATB_INDICES) - 1; - if (new_free_atb < MP_STATE_MEM(gc_first_free_atb_index)[bucket]) { - MP_STATE_MEM(gc_first_free_atb_index)[bucket] = new_free_atb; - } - if (new_free_atb > MP_STATE_MEM(gc_last_free_atb_index)) { - MP_STATE_MEM(gc_last_free_atb_index) = new_free_atb; + if ((block + new_blocks) / BLOCKS_PER_ATB < MP_STATE_MEM(gc_last_free_atb_index)) { + MP_STATE_MEM(gc_last_free_atb_index) = (block + new_blocks) / BLOCKS_PER_ATB; } GC_EXIT(); @@ -991,7 +909,7 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { } // can't resize inplace; try to find a new contiguous chain - void *ptr_out = gc_alloc(n_bytes, ftb_state, false); + void *ptr_out = gc_alloc(n_bytes, ftb_state); // check that the alloc succeeded if (ptr_out == NULL) { @@ -1024,7 +942,7 @@ bool gc_never_free(void *ptr) { last_reference_block = current_reference_block; // keep a record of last "proper" reference block current_reference_block = current_reference_block[0]; } - void **next_block = gc_alloc(BYTES_PER_BLOCK, false, true); + void **next_block = gc_alloc(BYTES_PER_BLOCK, false); if (next_block == NULL) { return false; } @@ -1149,13 +1067,13 @@ void gc_dump_alloc_table(void) { // This code prints "Q" for qstr-pool data, and "q" for qstr-str // data. It can be useful to see how qstrs are being allocated, // but is disabled by default because it is very slow. - for (qstr_pool_t *pool = MP_STATE_VM(last_pool); c == 'h' && pool != NULL; pool = pool->prev) { - if ((qstr_pool_t *)ptr == pool) { + for (const qstr_pool_t *pool = MP_STATE_VM(last_pool); c == 'h' && pool != NULL; pool = pool->prev) { + if ((const qstr_pool_t *)ptr == pool) { c = 'Q'; break; } - for (const byte **q = pool->qstrs, **q_top = pool->qstrs + pool->len; q < q_top; q++) { - if ((const byte *)ptr == *q) { + for (const char *const *q = pool->qstrs, *const *q_top = pool->qstrs + pool->len; q < q_top; q++) { + if ((const char *)ptr == *q) { c = 'q'; break; } diff --git a/py/gc.h b/py/gc.h index b9036ff4ba939..c88ac78006ecc 100644 --- a/py/gc.h +++ b/py/gc.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,15 +26,13 @@ #ifndef MICROPY_INCLUDED_PY_GC_H #define MICROPY_INCLUDED_PY_GC_H -#include +#include +#include #include "py/mpconfig.h" #include "py/mpstate.h" #include "py/misc.h" -#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / MP_BYTES_PER_OBJ_WORD) -#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK) - #define HEAP_PTR(ptr) ( \ MP_STATE_MEM(gc_pool_start) != 0 /* Not on the heap if it isn't inited */ \ && ptr >= (void *)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \ @@ -43,7 +41,7 @@ // ptr should be of type void* #define VERIFY_PTR(ptr) ( \ - ((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \ + ((uintptr_t)(ptr) & (MICROPY_BYTES_PER_GC_BLOCK - 1)) == 0 /* must be aligned on a block */ \ && HEAP_PTR(ptr) \ ) @@ -73,11 +71,10 @@ enum { GC_ALLOC_FLAG_HAS_FINALISER = 1, }; -void *gc_alloc(size_t n_bytes, unsigned int alloc_flags, bool long_lived); +void *gc_alloc(size_t n_bytes, unsigned int alloc_flags); void gc_free(void *ptr); // does not call finaliser size_t gc_nbytes(const void *ptr); bool gc_has_finaliser(const void *ptr); -void *gc_make_long_lived(void *old_ptr); void *gc_realloc(void *ptr, size_t n_bytes, bool allow_move); // Prevents a pointer from ever being freed because it establishes a permanent reference to it. Use diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c deleted file mode 100644 index 647c4f75b7754..0000000000000 --- a/py/gc_long_lived.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Scott Shawcroft for Adafruit Industries LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "py/emitglue.h" -#include "py/gc_long_lived.h" -#include "py/gc.h" -#include "py/mpstate.h" - -mp_obj_fun_bc_t *make_fun_bc_long_lived(mp_obj_fun_bc_t *fun_bc, uint8_t max_depth) { - #ifndef MICROPY_ENABLE_GC - return fun_bc; - #endif - if (fun_bc == NULL || MP_OBJ_FROM_PTR(fun_bc) == mp_const_none || max_depth == 0) { - return fun_bc; - } - fun_bc->bytecode = gc_make_long_lived((byte *)fun_bc->bytecode); - fun_bc->globals = make_dict_long_lived(fun_bc->globals, max_depth - 1); - for (uint32_t i = 0; i < gc_nbytes(fun_bc->const_table) / sizeof(mp_obj_t); i++) { - // Skip things that aren't allocated on the heap (and hence have zero bytes.) - if (gc_nbytes(MP_OBJ_TO_PTR(fun_bc->const_table[i])) == 0) { - continue; - } - // Try to detect raw code. - mp_raw_code_t *raw_code = MP_OBJ_TO_PTR(fun_bc->const_table[i]); - if (raw_code->kind == MP_CODE_BYTECODE) { - raw_code->fun_data = gc_make_long_lived((byte *)raw_code->fun_data); - raw_code->const_table = gc_make_long_lived((byte *)raw_code->const_table); - } - ((mp_uint_t *)fun_bc->const_table)[i] = (mp_uint_t)make_obj_long_lived( - (mp_obj_t)fun_bc->const_table[i], max_depth - 1); - - } - fun_bc->const_table = gc_make_long_lived((mp_uint_t *)fun_bc->const_table); - // extra_args stores keyword only argument default values. - size_t words = gc_nbytes(fun_bc) / sizeof(mp_uint_t *); - // Functions (mp_obj_fun_bc_t) have four pointers (base, globals, bytecode and const_table) - // before the variable length extra_args so remove them from the length. - for (size_t i = 0; i < words - 4; i++) { - if (MP_OBJ_TO_PTR(fun_bc->extra_args[i]) == NULL) { - continue; - } - if (mp_obj_is_type(fun_bc->extra_args[i], &mp_type_dict)) { - fun_bc->extra_args[i] = MP_OBJ_FROM_PTR(make_dict_long_lived(MP_OBJ_TO_PTR(fun_bc->extra_args[i]), max_depth - 1)); - } else { - fun_bc->extra_args[i] = make_obj_long_lived(fun_bc->extra_args[i], max_depth - 1); - } - - } - return gc_make_long_lived(fun_bc); -} - -mp_obj_property_t *make_property_long_lived(mp_obj_property_t *prop, uint8_t max_depth) { - #ifndef MICROPY_ENABLE_GC - return prop; - #endif - if (max_depth == 0) { - return prop; - } - prop->proxy[0] = make_obj_long_lived(prop->proxy[0], max_depth - 1); - prop->proxy[1] = make_obj_long_lived(prop->proxy[1], max_depth - 1); - prop->proxy[2] = make_obj_long_lived(prop->proxy[2], max_depth - 1); - return gc_make_long_lived(prop); -} - -mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth) { - #ifndef MICROPY_ENABLE_GC - return dict; - #endif - if (dict == NULL || max_depth == 0 || dict == &MP_STATE_VM(dict_main) || dict->map.is_fixed) { - return dict; - } - // Don't recurse unnecessarily. Return immediately if we've already seen this dict. - if (dict->map.scanning) { - return dict; - } - // Mark that we're processing this dict. - dict->map.scanning = 1; - - // Update all of the references first so that we reduce the chance of references to the old - // copies. - dict->map.table = gc_make_long_lived(dict->map.table); - for (size_t i = 0; i < dict->map.alloc; i++) { - if (mp_map_slot_is_filled(&dict->map, i)) { - mp_obj_t value = dict->map.table[i].value; - dict->map.table[i].value = make_obj_long_lived(value, max_depth - 1); - } - } - dict = gc_make_long_lived(dict); - // Done recursing through this dict. - dict->map.scanning = 0; - return dict; -} - -mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str) { - str->data = gc_make_long_lived((byte *)str->data); - return gc_make_long_lived(str); -} - -mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth) { - #ifndef MICROPY_ENABLE_GC - return obj; - #endif - if (MP_OBJ_TO_PTR(obj) == NULL) { - return obj; - } - // If not in the GC pool, do nothing. This can happen (at least) when - // there are frozen mp_type_bytes objects in ROM. - if (!VERIFY_PTR((void *)obj)) { - return obj; - } - if (mp_obj_is_type(obj, &mp_type_fun_bc)) { - mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(obj); - return MP_OBJ_FROM_PTR(make_fun_bc_long_lived(fun_bc, max_depth)); - } else if (mp_obj_is_type(obj, &mp_type_property)) { - mp_obj_property_t *prop = MP_OBJ_TO_PTR(obj); - return MP_OBJ_FROM_PTR(make_property_long_lived(prop, max_depth)); - } else if (mp_obj_is_type(obj, &mp_type_str) || mp_obj_is_type(obj, &mp_type_bytes)) { - mp_obj_str_t *str = MP_OBJ_TO_PTR(obj); - return MP_OBJ_FROM_PTR(make_str_long_lived(str)); - } else if (mp_obj_is_type(obj, &mp_type_type)) { - // Types are already long lived during creation. - return obj; - } else { - return MP_OBJ_FROM_PTR(gc_make_long_lived(MP_OBJ_TO_PTR(obj))); - } -} diff --git a/py/grammar.h b/py/grammar.h index 3b4ceb8c60c6d..285fbded2fdae 100644 --- a/py/grammar.h +++ b/py/grammar.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2020 Damien P. George + * Copyright (c) 2013-2020 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/lexer.c b/py/lexer.c index 0d6de0d522529..39e9662f63e65 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,8 +32,6 @@ #include "py/lexer.h" #include "py/runtime.h" -#include "supervisor/shared/translate/translate.h" - #if MICROPY_ENABLE_COMPILER #define TAB_SIZE (8) @@ -394,7 +392,6 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring) if (is_char(lex, '\\')) { next_char(lex); unichar c = CUR_CHAR(lex); - if (is_raw) { // raw strings allow escaping of quotes, but the backslash is also emitted vstr_add_char(&lex->vstr, '\\'); @@ -476,25 +473,23 @@ STATIC void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring) } } if (c != MP_LEXER_EOF) { - if (MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC) { - if (c < 0x110000 && lex->tok_kind == MP_TOKEN_STRING) { - vstr_add_char(&lex->vstr, c); - } else if (c < 0x100 && lex->tok_kind == MP_TOKEN_BYTES) { - vstr_add_byte(&lex->vstr, c); - } else { - // unicode character out of range - // this raises a generic SyntaxError; could provide more info - lex->tok_kind = MP_TOKEN_INVALID; - } - } else { - // without unicode everything is just added as an 8-bit byte - if (c < 0x100) { - vstr_add_byte(&lex->vstr, c); - } else { - // 8-bit character out of range - // this raises a generic SyntaxError; could provide more info - lex->tok_kind = MP_TOKEN_INVALID; - } + #if MICROPY_PY_BUILTINS_STR_UNICODE + if (c < 0x110000 && lex->tok_kind == MP_TOKEN_STRING) { + // Valid unicode character in a str object. + vstr_add_char(&lex->vstr, c); + } else if (c < 0x100 && lex->tok_kind == MP_TOKEN_BYTES) { + // Valid byte in a bytes object. + vstr_add_byte(&lex->vstr, c); + } + #else + if (c < 0x100) { + // Without unicode everything is just added as an 8-bit byte. + vstr_add_byte(&lex->vstr, c); + } + #endif + else { + // Character out of range; this raises a generic SyntaxError. + lex->tok_kind = MP_TOKEN_INVALID; } } } else { @@ -678,6 +673,7 @@ void mp_lexer_to_next(mp_lexer_t *lex) { skip_whitespace(lex, true); } while (is_string_or_bytes(lex)); + } else if (is_head_of_identifier(lex)) { lex->tok_kind = MP_TOKEN_NAME; diff --git a/py/lexer.h b/py/lexer.h index bcc1c04a683d8..8295dec0f715d 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -189,24 +189,15 @@ typedef struct _mp_lexer_t { mp_lexer_t *mp_lexer_new(qstr src_name, mp_reader_t reader); mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, size_t len, size_t free_len); -void mp_lexer_free(mp_lexer_t *lex); -void mp_lexer_to_next(mp_lexer_t *lex); - -/******************************************************************/ -// platform specific import function; must be implemented for a specific port -// TODO tidy up, rename, or put elsewhere - -typedef enum { - MP_IMPORT_STAT_NO_EXIST, - MP_IMPORT_STAT_DIR, - MP_IMPORT_STAT_FILE, -} mp_import_stat_t; - -mp_import_stat_t mp_import_stat(const char *path); +// If MICROPY_READER_POSIX or MICROPY_READER_VFS aren't enabled then +// this function must be implemented by the port. mp_lexer_t *mp_lexer_new_from_file(const char *filename); #if MICROPY_HELPER_LEXER_UNIX mp_lexer_t *mp_lexer_new_from_fd(qstr filename, int fd, bool close_fd); #endif +void mp_lexer_free(mp_lexer_t *lex); +void mp_lexer_to_next(mp_lexer_t *lex); + #endif // MICROPY_INCLUDED_PY_LEXER_H diff --git a/py/makemoduledefs.py b/py/makemoduledefs.py index aa2e5077ca8eb..9061cd890be82 100644 --- a/py/makemoduledefs.py +++ b/py/makemoduledefs.py @@ -1,89 +1,69 @@ -#!/usr/bin/env python - -# This pre-processor parses provided objects' c files for -# MP_REGISTER_MODULE(module_name, obj_module, enabled_define) -# These are used to generate a header with the required entries for -# "mp_rom_map_elem_t mp_builtin_module_table[]" in py/objmodule.c +""" +This pre-processor parses a single file containing a list of +MP_REGISTER_MODULE(module_name, obj_module) +These are used to generate a header with the required entries for +"mp_rom_map_elem_t mp_builtin_module_table[]" in py/objmodule.c +""" from __future__ import print_function +import sys import re import io -import os import argparse -pattern = re.compile(r"[\n;]\s*MP_REGISTER_MODULE\((.*?),\s*(.*?),\s*(.*?)\);", flags=re.DOTALL) - - -def find_c_file(obj_file, vpath): - """Search vpaths for the c file that matches the provided object_file. - - :param str obj_file: object file to find the matching c file for - :param List[str] vpath: List of base paths, similar to gcc vpath - :return: str path to c file or None - """ - c_file = None - relative_c_file = os.path.splitext(obj_file)[0] + ".c" - relative_c_file = relative_c_file.lstrip("/\\") - for p in vpath: - possible_c_file = os.path.join(p, relative_c_file) - if os.path.exists(possible_c_file): - c_file = possible_c_file - break - - return c_file +pattern = re.compile(r"\s*MP_REGISTER_MODULE\((.*?),\s*(.*?)\);", flags=re.DOTALL) -def find_module_registrations(c_file): - """Find any MP_REGISTER_MODULE definitions in the provided c file. +def find_module_registrations(filename): + """Find any MP_REGISTER_MODULE definitions in the provided file. - :param str c_file: path to c file to check - :return: List[(module_name, obj_module, enabled_define)] + :param str filename: path to file to check + :return: List[(module_name, obj_module)] """ global pattern - if c_file is None: - # No c file to match the object file, skip - return set() - - with io.open(c_file, encoding="utf-8") as c_file_obj: + with io.open(filename, encoding="utf-8") as c_file_obj: return set(re.findall(pattern, c_file_obj.read())) def generate_module_table_header(modules): """Generate header with module table entries for builtin modules. - :param List[(module_name, obj_module, enabled_define)] modules: module defs + :param List[(module_name, obj_module)] modules: module defs :return: None """ # Print header file for all external modules. - mod_defs = [] + mod_defs = set() print("// Automatically generated by makemoduledefs.py.\n") - print('#include "py/mpconfig.h"') - for module_name, obj_module, enabled_define in modules: + for module_name, obj_module in modules: mod_def = "MODULE_DEF_{}".format(module_name.upper()) - mod_defs.append(mod_def) + mod_defs.add(mod_def) + if "," in obj_module: + print( + "ERROR: Call to MP_REGISTER_MODULE({}, {}) should be MP_REGISTER_MODULE({}, {})\n".format( + module_name, obj_module, module_name, obj_module.split(",")[0] + ), + file=sys.stderr, + ) + sys.exit(1) print( ( - "#if ({enabled_define})\n" - " extern const struct _mp_obj_module_t {obj_module};\n" - " #define {mod_def} {{ MP_ROM_QSTR({module_name}), MP_ROM_PTR(&{obj_module}) }},\n" - "#else\n" - " #define {mod_def}\n" - "#endif\n" + "extern const struct _mp_obj_module_t {obj_module};\n" + "#undef {mod_def}\n" + "#define {mod_def} {{ MP_ROM_QSTR({module_name}), MP_ROM_PTR(&{obj_module}) }},\n" ).format( module_name=module_name, obj_module=obj_module, - enabled_define=enabled_define, mod_def=mod_def, ) ) print("\n#define MICROPY_REGISTERED_MODULES \\") - for mod_def in mod_defs: + for mod_def in sorted(mod_defs): print(" {mod_def} \\".format(mod_def=mod_def)) print("// MICROPY_REGISTERED_MODULES") @@ -91,19 +71,10 @@ def generate_module_table_header(modules): def main(): parser = argparse.ArgumentParser() - parser.add_argument( - "--vpath", default=".", help="comma separated list of folders to search for c files in" - ) - parser.add_argument("files", nargs="*", help="list of c files to search") + parser.add_argument("file", nargs=1, help="file with MP_REGISTER_MODULE definitions") args = parser.parse_args() - vpath = [p.strip() for p in args.vpath.split(",")] - - modules = set() - for obj_file in args.files: - c_file = find_c_file(obj_file, vpath) - modules |= find_module_registrations(c_file) - + modules = find_module_registrations(args.file[0]) generate_module_table_header(sorted(modules)) diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index d16bb0d09aa18..504fc31a15245 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -271,10 +271,10 @@ def esc_char(m): return re.sub(r"[^A-Za-z0-9_]", esc_char, qst) -def parse_input_headers(infiles): +def parse_input_headers_with_translations(infiles): qcfgs = {} qstrs = {} - i18ns = set() + translations = set() # add static qstrs for qstr in static_qstr_list: @@ -306,7 +306,7 @@ def parse_input_headers(infiles): match = re.match(r'^TRANSLATE\("(.*)"\)$', line) if match: - i18ns.add(match.group(1)) + translations.add(match.group(1)) continue # is this a QSTR line? @@ -348,16 +348,21 @@ def parse_input_headers(infiles): sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n") sys.exit(1) - return qcfgs, qstrs, i18ns + return qcfgs, qstrs, translations + + +# Used externally by mpy-tool.py. Don't pass back translations. +def parse_input_headers(infiles): + qcfgs, qstrs, translations = parse_input_headers_with_translations(infiles) + return (qcfgs, qstrs) -def escape_bytes(qstr): +def escape_bytes(qstr, qbytes): if all(32 <= ord(c) <= 126 and c != "\\" and c != '"' for c in qstr): # qstr is all printable ASCII so render it as-is (for easier debugging) return qstr else: # qstr contains non-printable codes so render entire thing as hex pairs - qbytes = bytes_cons(qstr, "utf8") return "".join(("\\x%02x" % b) for b in qbytes) @@ -368,11 +373,11 @@ def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr): if qlen >= (1 << (8 * cfg_bytes_len)): print("qstr is too long:", qstr) assert False - qdata = escape_bytes(qstr) + qdata = escape_bytes(qstr, qbytes) return '%d, %d, "%s"' % (qhash, qlen, qdata) -def print_qstr_data(qcfgs, qstrs, i18ns): +def print_qstr_data(qcfgs, qstrs, translations): # get config variables cfg_bytes_len = int(qcfgs["BYTES_IN_LEN"]) cfg_bytes_hash = int(qcfgs["BYTES_IN_HASH"]) @@ -395,24 +400,16 @@ def print_qstr_data(qcfgs, qstrs, i18ns): print( "// Enumerate translated texts but don't actually include translations. Instead, the linker will link them in." ) - for i, original in enumerate(i18ns): + for i, original in enumerate(sorted(translations)): print('TRANSLATION("{}", {})'.format(original, i)) print() print("// {} bytes worth of qstr".format(total_qstr_size)) -def print_qstr_enums(qstrs): - # print out the starter of the generated C header file - print("// This file was automatically generated by makeqstrdata.py") - print("") - - # add NULL qstr with no hash or data - print("QENUM(MP_QSTRnull)") - - # go through each qstr and print it out - for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]): - print("QENUM(MP_QSTR_%s)" % (ident,)) +def do_work(infiles): + qcfgs, qstrs, translations = parse_input_headers_with_translations(infiles) + print_qstr_data(qcfgs, qstrs, translations) if __name__ == "__main__": @@ -424,19 +421,7 @@ def print_qstr_enums(qstrs): parser.add_argument( "infiles", metavar="N", type=str, nargs="+", help="an integer for the accumulator" ) - parser.add_argument( - "--output_type", - default="enums", - type=str, - help="output definitions", - choices=("enums", "data"), - ) args = parser.parse_args() - qcfgs, qstrs, i18ns = parse_input_headers(args.infiles) - if args.output_type == "data": - i18ns = sorted(i18ns) - print_qstr_data(qcfgs, qstrs, i18ns) - else: - print_qstr_enums(qstrs) + do_work(args.infiles) diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py index 974227f2a5f4e..adf6195389c33 100644 --- a/py/makeqstrdefs.py +++ b/py/makeqstrdefs.py @@ -2,7 +2,7 @@ This script processes the output from the C preprocessor and extracts all qstr. Each qstr is transformed into a qstr definition of the form 'Q(...)'. -This script works with Python 2.6, 2.7, 3.3 and 3.4. +This script works with Python 3.x """ from __future__ import print_function @@ -14,20 +14,8 @@ import sys import multiprocessing, multiprocessing.dummy -# Python 2/3 compatibility: -# - iterating through bytes is different -# - codepoint2name lives in a different module -import platform -if platform.python_version_tuple()[0] == "2": - bytes_cons = lambda val, enc=None: bytearray(val) - from htmlentitydefs import name2codepoint -elif platform.python_version_tuple()[0] == "3": - bytes_cons = bytes - from html.entities import name2codepoint - - unichr = chr -# end compatibility code +from html.entities import name2codepoint # Blocklist of qstrings that are specially handled in further # processing and should be ignored @@ -67,6 +55,23 @@ del name2codepoint["or"] del name2codepoint["not"] +# Extract MP_QSTR_FOO macros. +_MODE_QSTR = "qstr" + +# Extract MP_COMPRESSED_ROM_TEXT("") macros. (Which come from MP_ERROR_TEXT) +_MODE_COMPRESS = "compress" + +# Extract MP_REGISTER_MODULE(...) macros. +_MODE_MODULE = "module" + + +def is_c_source(fname): + return os.path.splitext(fname)[1] in [".c"] + + +def is_cxx_source(fname): + return os.path.splitext(fname)[1] in [".cc", ".cp", ".cxx", ".cpp", ".CPP", ".c++", ".C"] + def preprocess(): if any(src in args.dependencies for src in args.changed_sources): @@ -78,9 +83,9 @@ def preprocess(): csources = [] cxxsources = [] for source in sources: - if source.endswith(".cpp"): + if is_cxx_source(source): cxxsources.append(source) - elif source.endswith(".c"): + elif is_c_source(source): csources.append(source) try: os.makedirs(os.path.dirname(args.output[0])) @@ -113,7 +118,7 @@ def write_out(fname, output): if output: for m, r in [("/", "__"), ("\\", "__"), (":", "@"), ("..", "@@")]: fname = fname.replace(m, r) - with open(args.output_dir + "/" + fname + ".qstr", "w") as f: + with open(args.output_dir + "/" + fname + "." + args.mode, "w") as f: f.write("\n".join(output) + "\n") @@ -122,17 +127,21 @@ def qstr_unescape(qstr): if "__" + name + "__" in qstr: continue if "_" + name + "_" in qstr: - qstr = qstr.replace("_" + name + "_", str(unichr(name2codepoint[name]))) + qstr = qstr.replace("_" + name + "_", str(chr(name2codepoint[name]))) return qstr def process_file(f): - re_line = re.compile(r"#[line]*\s(\d+)\s\"([^\"]+)\"") - re_qstr = re.compile(r"MP_QSTR_[_a-zA-Z0-9]+") + re_line = re.compile(r"#[line]*\s\d+\s\"([^\"]+)\"") + if args.mode == _MODE_QSTR: + re_match = re.compile(r"MP_QSTR_[_a-zA-Z0-9]+") + elif args.mode == _MODE_COMPRESS: + re_match = re.compile(r'MP_COMPRESSED_ROM_TEXT\("([^"]*)"\)') + elif args.mode == _MODE_MODULE: + re_match = re.compile(r"MP_REGISTER_MODULE\(.*?,\s*.*?\);") re_translate = re.compile(r"translate\(\"((?:(?=(\\?))\2.)*?)\"\)") output = [] last_fname = None - lineno = 0 for line in f: if line.isspace(): continue @@ -140,8 +149,7 @@ def process_file(f): if line.startswith(("# ", "#line")): m = re_line.match(line) assert m is not None - lineno = int(m.group(1)) - fname = m.group(2) + fname = m.group(1) if os.path.splitext(fname)[1] not in [".c", ".cpp"]: continue if fname != last_fname: @@ -149,13 +157,16 @@ def process_file(f): output = [] last_fname = fname continue - for match in re_qstr.findall(line): - name = match.replace("MP_QSTR_", "") - if name not in QSTRING_BLOCK_LIST: - output.append("Q(" + qstr_unescape(name) + ")") + for match in re_match.findall(line): + if args.mode == _MODE_QSTR: + name = match.replace("MP_QSTR_", "") + if name not in QSTRING_BLOCK_LIST: + output.append("Q(" + qstr_unescape(name) + ")") + elif args.mode in (_MODE_COMPRESS, _MODE_MODULE): + output.append(match) + for match in re_translate.findall(line): output.append('TRANSLATE("' + match[0] + '")') - lineno += 1 if last_fname: write_out(last_fname, output) @@ -169,7 +180,7 @@ def cat_together(): hasher = hashlib.md5() all_lines = [] outf = open(args.output_dir + "/out", "wb") - for fname in glob.glob(args.output_dir + "/*.qstr"): + for fname in glob.glob(args.output_dir + "/*." + args.mode): with open(fname, "rb") as f: lines = f.readlines() all_lines += lines @@ -186,8 +197,13 @@ def cat_together(): old_hash = f.read() except IOError: pass + mode_full = "QSTR" + if args.mode == _MODE_COMPRESS: + mode_full = "Compressed data" + elif args.mode == _MODE_MODULE: + mode_full = "Module registrations" if old_hash != new_hash: - print("QSTR updated") + print(mode_full, "updated") try: # rename below might fail if file exists os.remove(args.output_file) @@ -197,12 +213,12 @@ def cat_together(): with open(args.output_file + ".hash", "w") as f: f.write(new_hash) else: - print("QSTR not updated") + print(mode_full, "not updated") if __name__ == "__main__": - if len(sys.argv) != 5: - print("usage: %s command input_filename output_dir output_file" % sys.argv[0]) + if len(sys.argv) < 6: + print("usage: %s command mode input_filename output_dir output_file" % sys.argv[0]) sys.exit(2) class Args: @@ -210,9 +226,45 @@ class Args: args = Args() args.command = sys.argv[1] - args.input_filename = sys.argv[2] - args.output_dir = sys.argv[3] - args.output_file = sys.argv[4] + + if args.command == "pp": + named_args = { + s: [] + for s in [ + "pp", + "output", + "cflags", + "cxxflags", + "sources", + "changed_sources", + "dependencies", + ] + } + + for arg in sys.argv[1:]: + if arg in named_args: + current_tok = arg + else: + named_args[current_tok].append(arg) + + if not named_args["pp"] or len(named_args["output"]) != 1: + print("usage: %s %s ..." % (sys.argv[0], " ... ".join(named_args))) + sys.exit(2) + + for k, v in named_args.items(): + setattr(args, k, v) + + preprocess() + sys.exit(0) + + args.mode = sys.argv[2] + args.input_filename = sys.argv[3] # Unused for command=cat + args.output_dir = sys.argv[4] + args.output_file = None if len(sys.argv) == 5 else sys.argv[5] # Unused for command=split + + if args.mode not in (_MODE_QSTR, _MODE_COMPRESS, _MODE_MODULE): + print("error: mode %s unrecognised" % sys.argv[2]) + sys.exit(2) try: os.makedirs(args.output_dir) diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py index b0d00a694e209..11d162ecea698 100644 --- a/py/makeversionhdr.py +++ b/py/makeversionhdr.py @@ -97,6 +97,8 @@ def make_version_header(filename): #define MICROPY_VERSION_MINOR (%s) #define MICROPY_VERSION_MICRO (%s) #define MICROPY_VERSION_STRING "%s" +// Combined version as a 32-bit number for convenience +#define MICROPY_VERSION (MICROPY_VERSION_MAJOR << 16 | MICROPY_VERSION_MINOR << 8 | MICROPY_VERSION_MICRO) #define MICROPY_FULL_VERSION_INFO "Adafruit CircuitPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE "; " MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME """ % ( git_tag, diff --git a/py/malloc.c b/py/malloc.c index 7200285687a7e..efdff75396980 100644 --- a/py/malloc.c +++ b/py/malloc.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -56,8 +56,8 @@ #undef malloc #undef free #undef realloc -#define malloc_ll(b, ll) gc_alloc((b), false, (ll)) -#define malloc_with_finaliser(b, ll) gc_alloc((b), true, (ll)) +#define malloc(b) gc_alloc((b), false) +#define malloc_with_finaliser(b) gc_alloc((b), true) #define free gc_free #define realloc(ptr, n) gc_realloc(ptr, n, true) #define realloc_ext(ptr, n, mv) gc_realloc(ptr, n, mv) @@ -69,9 +69,6 @@ #error MICROPY_ENABLE_FINALISER requires MICROPY_ENABLE_GC #endif -#define malloc_ll(b, ll) malloc(b) -#define malloc_with_finaliser(b) malloc((b)) - STATIC void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) { if (allow_move) { return realloc(ptr, n_bytes); @@ -85,8 +82,8 @@ STATIC void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) { #endif // MICROPY_ENABLE_GC -void *m_malloc(size_t num_bytes, bool long_lived) { - void *ptr = malloc_ll(num_bytes, long_lived); +void *m_malloc(size_t num_bytes) { + void *ptr = malloc(num_bytes); if (ptr == NULL && num_bytes != 0) { m_malloc_fail(num_bytes); } @@ -99,8 +96,8 @@ void *m_malloc(size_t num_bytes, bool long_lived) { return ptr; } -void *m_malloc_maybe(size_t num_bytes, bool long_lived) { - void *ptr = malloc_ll(num_bytes, long_lived); +void *m_malloc_maybe(size_t num_bytes) { + void *ptr = malloc(num_bytes); #if MICROPY_MEM_STATS MP_STATE_MEM(total_bytes_allocated) += num_bytes; MP_STATE_MEM(current_bytes_allocated) += num_bytes; @@ -111,8 +108,8 @@ void *m_malloc_maybe(size_t num_bytes, bool long_lived) { } #if MICROPY_ENABLE_FINALISER -void *m_malloc_with_finaliser(size_t num_bytes, bool long_lived) { - void *ptr = malloc_with_finaliser(num_bytes, long_lived); +void *m_malloc_with_finaliser(size_t num_bytes) { + void *ptr = malloc_with_finaliser(num_bytes); if (ptr == NULL && num_bytes != 0) { m_malloc_fail(num_bytes); } @@ -126,8 +123,8 @@ void *m_malloc_with_finaliser(size_t num_bytes, bool long_lived) { } #endif -void *m_malloc0(size_t num_bytes, bool long_lived) { - void *ptr = m_malloc(num_bytes, long_lived); +void *m_malloc0(size_t num_bytes) { + void *ptr = m_malloc(num_bytes); // If this config is set then the GC clears all memory, so we don't need to. #if !MICROPY_GC_CONSERVATIVE_CLEAR memset(ptr, 0, num_bytes); @@ -136,10 +133,11 @@ void *m_malloc0(size_t num_bytes, bool long_lived) { } #if MICROPY_MALLOC_USES_ALLOCATED_SIZE -void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes) { +void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes) #else -void *m_realloc(void *ptr, size_t new_num_bytes) { - #endif +void *m_realloc(void *ptr, size_t new_num_bytes) +#endif +{ void *new_ptr = realloc(ptr, new_num_bytes); if (new_ptr == NULL && new_num_bytes != 0) { m_malloc_fail(new_num_bytes); @@ -164,10 +162,11 @@ void *m_realloc(void *ptr, size_t new_num_bytes) { } #if MICROPY_MALLOC_USES_ALLOCATED_SIZE -void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes, bool allow_move) { +void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes, bool allow_move) #else -void *m_realloc_maybe(void *ptr, size_t new_num_bytes, bool allow_move) { - #endif +void *m_realloc_maybe(void *ptr, size_t new_num_bytes, bool allow_move) +#endif +{ void *new_ptr = realloc_ext(ptr, new_num_bytes, allow_move); #if MICROPY_MEM_STATS // At first thought, "Total bytes allocated" should only grow, @@ -192,10 +191,11 @@ void *m_realloc_maybe(void *ptr, size_t new_num_bytes, bool allow_move) { } #if MICROPY_MALLOC_USES_ALLOCATED_SIZE -void m_free(void *ptr, size_t num_bytes) { +void m_free(void *ptr, size_t num_bytes) #else -void m_free(void *ptr) { - #endif +void m_free(void *ptr) +#endif +{ free(ptr); #if MICROPY_MEM_STATS MP_STATE_MEM(current_bytes_allocated) -= num_bytes; @@ -239,7 +239,7 @@ STATIC size_t m_tracked_count_links(size_t *nb) { #endif void *m_tracked_calloc(size_t nmemb, size_t size) { - m_tracked_node_t *node = m_malloc_maybe(sizeof(m_tracked_node_t) + nmemb * size, false); + m_tracked_node_t *node = m_malloc_maybe(sizeof(m_tracked_node_t) + nmemb * size); if (node == NULL) { return NULL; } @@ -298,7 +298,7 @@ void m_tracked_free(void *ptr_in) { ); } -#endif +#endif // MICROPY_TRACKED_ALLOC #if MICROPY_MEM_STATS size_t m_get_total_bytes_allocated(void) { diff --git a/py/map.c b/py/map.c index 092adf94ee128..b194250cb4f59 100644 --- a/py/map.c +++ b/py/map.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,8 +33,6 @@ #include "py/misc.h" #include "py/runtime.h" -#include "supervisor/linker.h" - #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) #else // don't print debugging info diff --git a/py/misc.h b/py/misc.h index 1ced7c622e29c..816d6446b1c6d 100644 --- a/py/misc.h +++ b/py/misc.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -63,26 +63,21 @@ typedef unsigned int uint; // TODO make a lazy m_renew that can increase by a smaller amount than requested (but by at least 1 more element) -#define m_new(type, num) ((type *)(m_malloc(sizeof(type) * (num), false))) -#define m_new_ll(type, num) ((type *)(m_malloc(sizeof(type) * (num), true))) -#define m_new_maybe(type, num) ((type *)(m_malloc_maybe(sizeof(type) * (num), false))) -#define m_new_ll_maybe(type, num) ((type *)(m_malloc_maybe(sizeof(type) * (num), true))) -#define m_new0(type, num) ((type *)(m_malloc0(sizeof(type) * (num), false))) -#define m_new0_ll(type, num) ((type *)(m_malloc0(sizeof(type) * (num), true))) +#define m_new(type, num) ((type *)(m_malloc(sizeof(type) * (num)))) +#define m_new_ll(type, num) m_new(type, num) // CIRCUITPY: clue to long-lived allocator +#define m_new_maybe(type, num) ((type *)(m_malloc_maybe(sizeof(type) * (num)))) +#define m_new0(type, num) ((type *)(m_malloc0(sizeof(type) * (num)))) #define m_new_obj(type) (m_new(type, 1)) -#define m_new_ll_obj(type) (m_new_ll(type, 1)) #define m_new_obj_maybe(type) (m_new_maybe(type, 1)) -#define m_new_obj_var(obj_type, var_type, var_num) ((obj_type *)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num), false)) -#define m_new_obj_var_maybe(obj_type, var_type, var_num) ((obj_type *)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num), false)) -#define m_new_ll_obj_var_maybe(obj_type, var_type, var_num) ((obj_type *)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num), true)) +#define m_new_obj_var(obj_type, var_type, var_num) ((obj_type *)m_malloc(sizeof(obj_type) + sizeof(var_type) * (var_num))) +#define m_new_obj_var_maybe(obj_type, var_type, var_num) ((obj_type *)m_malloc_maybe(sizeof(obj_type) + sizeof(var_type) * (var_num))) #if MICROPY_ENABLE_FINALISER -#define m_new_obj_with_finaliser(type) ((type *)(m_malloc_with_finaliser(sizeof(type), false))) -#define m_new_obj_var_with_finaliser(type, var_type, var_num) ((type *)m_malloc_with_finaliser(sizeof(type) + sizeof(var_type) * (var_num), false)) -#define m_new_ll_obj_with_finaliser(type) ((type *)(m_malloc_with_finaliser(sizeof(type), true))) +#define m_new_obj_with_finaliser(type) ((type *)(m_malloc_with_finaliser(sizeof(type)))) +#define m_new_ll_obj_with_finaliser(type) m_new_obj_with_finaliser(type) // CIRCUITPY: clue to long-lived allocator +#define m_new_obj_var_with_finaliser(type, var_type, var_num) ((type *)m_malloc_with_finaliser(sizeof(type) + sizeof(var_type) * (var_num))) #else #define m_new_obj_with_finaliser(type) m_new_obj(type) #define m_new_obj_var_with_finaliser(type, var_type, var_num) m_new_obj_var(type, var_type, var_num) -#define m_new_ll_obj_with_finaliser(type) m_new_ll_obj(type) #endif #if MICROPY_MALLOC_USES_ALLOCATED_SIZE #define m_renew(type, ptr, old_num, new_num) ((type *)(m_realloc((ptr), sizeof(type) * (old_num), sizeof(type) * (new_num)))) @@ -97,10 +92,10 @@ typedef unsigned int uint; #endif #define m_del_obj(type, ptr) (m_del(type, ptr, 1)) -void *m_malloc(size_t num_bytes, bool long_lived); -void *m_malloc_maybe(size_t num_bytes, bool long_lived); -void *m_malloc_with_finaliser(size_t num_bytes, bool long_lived); -void *m_malloc0(size_t num_bytes, bool long_lived); +void *m_malloc(size_t num_bytes); +void *m_malloc_maybe(size_t num_bytes); +void *m_malloc_with_finaliser(size_t num_bytes); +void *m_malloc0(size_t num_bytes); #if MICROPY_MALLOC_USES_ALLOCATED_SIZE void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes); void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes, bool allow_move); @@ -279,4 +274,66 @@ typedef union _mp_float_union_t { #endif // MICROPY_PY_BUILTINS_FLOAT +/** ROM string compression *************/ + +#if MICROPY_ROM_TEXT_COMPRESSION + +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE +#error "MICROPY_ERROR_REPORTING_NONE requires MICROPY_ROM_TEXT_COMPRESSION disabled" +#endif + +#ifdef NO_QSTR + +// Compression enabled but doing QSTR extraction. +// So leave MP_COMPRESSED_ROM_TEXT in place for makeqstrdefs.py / makecompresseddata.py to find them. + +#else + +// Compression enabled and doing a regular build. +// Map MP_COMPRESSED_ROM_TEXT to the compressed strings. + +// Force usage of the MP_ERROR_TEXT macro by requiring an opaque type. +typedef struct { + #ifdef __clang__ + // Fix "error: empty struct has size 0 in C, size 1 in C++". + char dummy; + #endif +} *mp_rom_error_text_t; + +#include + +inline __attribute__((always_inline)) const char *MP_COMPRESSED_ROM_TEXT(const char *msg) { + // "genhdr/compressed.data.h" contains an invocation of the MP_MATCH_COMPRESSED macro for each compressed string. + // The giant if(strcmp) tree is optimized by the compiler, which turns this into a direct return of the compressed data. + #define MP_MATCH_COMPRESSED(a, b) if (strcmp(msg, a) == 0) { return b; } else + + // It also contains a single invocation of the MP_COMPRESSED_DATA macro, we don't need that here. + #define MP_COMPRESSED_DATA(x) + + #include "genhdr/compressed.data.h" + +#undef MP_COMPRESSED_DATA +#undef MP_MATCH_COMPRESSED + + return msg; +} + +#endif + +#else + +// Compression not enabled, just make it a no-op. + +typedef const char *mp_rom_error_text_t; +#define MP_COMPRESSED_ROM_TEXT(x) x + +#endif // MICROPY_ROM_TEXT_COMPRESSION + +// Might add more types of compressed text in the future. +// For now, forward directly to MP_COMPRESSED_ROM_TEXT. +// CIRCUITPY: MP_ERROR_TEXT() -> translate() +#if !CIRCUITPY +#define MP_ERROR_TEXT(x) (mp_rom_error_text_t)MP_COMPRESSED_ROM_TEXT(x) +#endif + #endif // MICROPY_INCLUDED_PY_MISC_H diff --git a/py/mkenv.mk b/py/mkenv.mk index e2cdb2ddb6e16..a53e030aed440 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -13,25 +13,36 @@ THIS_MAKEFILE := $(lastword $(MAKEFILE_LIST)) TOP := $(patsubst %/py/mkenv.mk,%,$(THIS_MAKEFILE)) # Turn on increased build verbosity by defining BUILD_VERBOSE in your main -# Makefile or in your environment. You can also use V=1 on the make command -# line. +# Makefile or in your environment. You can also use V="steps commands rules" or any combination thereof +# on the make command line. ifeq ("$(origin V)", "command line") BUILD_VERBOSE=$(V) endif + ifndef BUILD_VERBOSE -$(info Use make V=1, make V=2 or set BUILD_VERBOSE similarly in your environment to increase build verbosity.) -BUILD_VERBOSE = 0 +$(info - Verbosity options: any combination of "steps commands rules", as `make V=...` or env var BUILD_VERBOSE) +BUILD_VERBOSE = "" endif -ifeq ($(BUILD_VERBOSE),0) -Q = @ -STEPECHO = @: -else ifeq ($(BUILD_VERBOSE),1) -Q = @ + +ifneq ($(filter steps,$(BUILD_VERBOSE)),) STEPECHO = @echo else +STEPECHO = @: +endif + +ifneq ($(filter commands,$(BUILD_VERBOSE)),) Q = -STEPECHO = @echo +else +Q = @ +endif + +ifneq ($(filter rules,$(BUILD_VERBOSE)),) +# This clever shell redefinition will print out the makefile line that is causing an action. +# Note that -j can cause the order to be confusing. +# https://www.cmcrossroads.com/article/tracing-rule-execution-gnu-make +OLD_SHELL := $(SHELL) +SHELL = $(warning BUILDING $@)$(OLD_SHELL) endif # default settings; can be overridden in main Makefile diff --git a/py/mkrules.cmake b/py/mkrules.cmake index cb5fdabf6b933..d0dc0196253ac 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -2,13 +2,15 @@ set(MICROPY_GENHDR_DIR "${CMAKE_BINARY_DIR}/genhdr") set(MICROPY_MPVERSION "${MICROPY_GENHDR_DIR}/mpversion.h") -set(MICROPY_MODULEDEFS "${MICROPY_GENHDR_DIR}/moduledefs.h") set(MICROPY_QSTRDEFS_PY "${MICROPY_PY_DIR}/qstrdefs.h") set(MICROPY_QSTRDEFS_LAST "${MICROPY_GENHDR_DIR}/qstr.i.last") set(MICROPY_QSTRDEFS_SPLIT "${MICROPY_GENHDR_DIR}/qstr.split") set(MICROPY_QSTRDEFS_COLLECTED "${MICROPY_GENHDR_DIR}/qstrdefs.collected.h") set(MICROPY_QSTRDEFS_PREPROCESSED "${MICROPY_GENHDR_DIR}/qstrdefs.preprocessed.h") set(MICROPY_QSTRDEFS_GENERATED "${MICROPY_GENHDR_DIR}/qstrdefs.generated.h") +set(MICROPY_MODULEDEFS_SPLIT "${MICROPY_GENHDR_DIR}/moduledefs.split") +set(MICROPY_MODULEDEFS_COLLECTED "${MICROPY_GENHDR_DIR}/moduledefs.collected") +set(MICROPY_MODULEDEFS "${MICROPY_GENHDR_DIR}/moduledefs.h") # Need to do this before extracting MICROPY_CPP_DEF below. Rest of frozen # manifest handling is at the end of this file. @@ -43,6 +45,7 @@ find_package(Python3 REQUIRED COMPONENTS Interpreter) target_sources(${MICROPY_TARGET} PRIVATE ${MICROPY_MPVERSION} ${MICROPY_QSTRDEFS_GENERATED} + ${MICROPY_MODULEDEFS} ) # Command to force the build of another command @@ -62,15 +65,6 @@ add_custom_command( DEPENDS MICROPY_FORCE_BUILD ) -# Generate moduledefs.h - -add_custom_command( - OUTPUT ${MICROPY_MODULEDEFS} - COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makemoduledefs.py --vpath="/" ${MICROPY_SOURCE_QSTR} > ${MICROPY_MODULEDEFS} - DEPENDS ${MICROPY_MPVERSION} - ${MICROPY_SOURCE_QSTR} -) - # Generate qstrs # If any of the dependencies in this rule change then the C-preprocessor step must be run. @@ -79,7 +73,7 @@ add_custom_command( add_custom_command( OUTPUT ${MICROPY_QSTRDEFS_LAST} COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py pp ${CMAKE_C_COMPILER} -E output ${MICROPY_GENHDR_DIR}/qstr.i.last cflags ${MICROPY_CPP_FLAGS} -DNO_QSTR cxxflags ${MICROPY_CPP_FLAGS} -DNO_QSTR sources ${MICROPY_SOURCE_QSTR} - DEPENDS ${MICROPY_MODULEDEFS} + DEPENDS ${MICROPY_MPVERSION} ${MICROPY_SOURCE_QSTR} VERBATIM COMMAND_EXPAND_LISTS @@ -120,6 +114,31 @@ add_custom_command( COMMAND_EXPAND_LISTS ) +# Generate moduledefs.h + +add_custom_command( + OUTPUT ${MICROPY_MODULEDEFS_SPLIT} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py split module ${MICROPY_GENHDR_DIR}/qstr.i.last ${MICROPY_GENHDR_DIR}/module _ + COMMAND touch ${MICROPY_MODULEDEFS_SPLIT} + DEPENDS ${MICROPY_QSTRDEFS_LAST} + VERBATIM + COMMAND_EXPAND_LISTS +) + +add_custom_command( + OUTPUT ${MICROPY_MODULEDEFS_COLLECTED} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py cat module _ ${MICROPY_GENHDR_DIR}/module ${MICROPY_MODULEDEFS_COLLECTED} + DEPENDS ${MICROPY_MODULEDEFS_SPLIT} + VERBATIM + COMMAND_EXPAND_LISTS +) + +add_custom_command( + OUTPUT ${MICROPY_MODULEDEFS} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makemoduledefs.py ${MICROPY_MODULEDEFS_COLLECTED} > ${MICROPY_MODULEDEFS} + DEPENDS ${MICROPY_MODULEDEFS_COLLECTED} +) + # Build frozen code if enabled if(MICROPY_FROZEN_MANIFEST) @@ -159,3 +178,10 @@ if(MICROPY_FROZEN_MANIFEST) VERBATIM ) endif() + +# Update submodules +if(ECHO_SUBMODULES) + # If cmake is run with GIT_SUBMODULES defined on command line, process the port / board + # settings then print the final GIT_SUBMODULES variable as a fatal error and exit. + message(FATAL_ERROR "GIT_SUBMODULES=${GIT_SUBMODULES}") +endif() diff --git a/py/mkrules.mk b/py/mkrules.mk index 09ed82ac5b7e2..5b871af62ba45 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -7,6 +7,24 @@ endif # Extra deps that need to happen before object compilation. OBJ_EXTRA_ORDER_DEPS = +# Generate moduledefs.h. +OBJ_EXTRA_ORDER_DEPS += $(HEADER_BUILD)/moduledefs.h + +ifeq ($(MICROPY_ROM_TEXT_COMPRESSION),1) +# If compression is enabled, trigger the build of compressed.data.h... +OBJ_EXTRA_ORDER_DEPS += $(HEADER_BUILD)/compressed.data.h +# ...and enable the MP_COMPRESSED_ROM_TEXT macro (used by MP_ERROR_TEXT). +CFLAGS += -DMICROPY_ROM_TEXT_COMPRESSION=1 +endif + +# QSTR generation uses the same CFLAGS, with these modifications. +QSTR_GEN_FLAGS = -DNO_QSTR +# Note: := to force evalulation immediately. +QSTR_GEN_CFLAGS := $(CFLAGS) +QSTR_GEN_CFLAGS += $(QSTR_GEN_FLAGS) +QSTR_GEN_CXXFLAGS := $(CXXFLAGS) +QSTR_GEN_CXXFLAGS += $(QSTR_GEN_FLAGS) + # This file expects that OBJ contains a list of all of the object files. # The directory portion of each object file is used to locate the source # and should not contain any ..'s but rather be relative to the top of the @@ -57,28 +75,18 @@ $(Q)$(CXX) $(CXXFLAGS) -c -MD -o $@ $< $(RM) -f $(@:.o=.d) endef -vpath %.c . $(TOP) $(USER_C_MODULES) $(DEVICES_MODULES) -$(BUILD)/%.o: %.c | $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/qstrdefs.enum.h +# frozen.c and frozen_mpy.c are created in $(BUILD), so add it to the vpath as well. +vpath %.c . $(TOP) $(USER_C_MODULES) $(DEVICES_MODULES) $(BUILD) +$(BUILD)/%.o: %.c $(call compile_c) vpath %.cpp . $(TOP) $(USER_C_MODULES) -$(BUILD)/%.o: %.cpp | $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/qstrdefs.enum.h +$(BUILD)/%.o: %.cpp $(call compile_cxx) -QSTR_GEN_EXTRA_CFLAGS += -DNO_QSTR -x c - -# frozen.c and frozen_mpy.c are created in $(BUILD), so use our rule -# for those as well. -vpath %.c . $(BUILD) -$(BUILD)/%.o: %.c - $(call compile_c) - -QSTR_GEN_EXTRA_CFLAGS += -I$(BUILD)/tmp - -vpath %.c . $(TOP) $(USER_C_MODULES) $(DEVICES_MODULES) $(BUILD)/%.pp: %.c $(STEPECHO) "PreProcess $<" - $(Q)$(CPP) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $< + $(Q)$(CPP) $(CFLAGS) -Wp,-C,-dD,-dI -o $@ $< # The following rule uses | to create an order only prerequisite. Order only # prerequisites only get built if they don't exist. They don't cause timestamp @@ -89,20 +97,45 @@ $(BUILD)/%.pp: %.c # the right .o's to get recompiled if the generated.h file changes. Adding # an order-only dependency to all of the .o's will cause the generated .h # to get built before we try to compile any of them. -$(OBJ): | $(HEADER_BUILD)/mpversion.h +$(OBJ): | $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/mpversion.h $(OBJ_EXTRA_ORDER_DEPS) # The logic for qstr regeneration (applied by makeqstrdefs.py) is: # - if anything in QSTR_GLOBAL_DEPENDENCIES is newer, then process all source files ($^) # - else, if list of newer prerequisites ($?) is not empty, then process just these ($?) # - else, process all source files ($^) [this covers "make -B" which can set $? to empty] -$(HEADER_BUILD)/qstr.split: $(SRC_QSTR) $(SRC_QSTR_PREPROCESSOR) $(QSTR_GLOBAL_DEPENDENCIES) $(HEADER_BUILD)/moduledefs.h | $(HEADER_BUILD)/mpversion.h $(PY_SRC)/genlast.py +# See more information about this process in docs/develop/qstr.rst. +$(HEADER_BUILD)/qstr.i.last: $(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) | $(QSTR_GLOBAL_REQUIREMENTS) + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py pp $(CPP) output $(HEADER_BUILD)/qstr.i.last cflags $(QSTR_GEN_CFLAGS) cxxflags $(QSTR_GEN_CXXFLAGS) sources $^ dependencies $(QSTR_GLOBAL_DEPENDENCIES) changed_sources $? + +$(HEADER_BUILD)/qstr.split: $(HEADER_BUILD)/qstr.i.last + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py split qstr $< $(HEADER_BUILD)/qstr _ + $(Q)$(TOUCH) $@ + +$(QSTR_DEFS_COLLECTED): $(HEADER_BUILD)/qstr.split + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py cat qstr _ $(HEADER_BUILD)/qstr $@ + +# Module definitions via MP_REGISTER_MODULE. +$(HEADER_BUILD)/moduledefs.split: $(HEADER_BUILD)/qstr.i.last + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py split module $< $(HEADER_BUILD)/module _ + $(Q)$(TOUCH) $@ + +$(HEADER_BUILD)/moduledefs.collected: $(HEADER_BUILD)/moduledefs.split + $(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py cat module _ $(HEADER_BUILD)/module $@ + +# Compressed error strings. +$(HEADER_BUILD)/compressed.split: $(HEADER_BUILD)/qstr.i.last $(STEPECHO) "GEN $@" - $(Q)$(PYTHON) $(PY_SRC)/genlast.py $(HEADER_BUILD)/qstr $(if $(filter $?,$(QSTR_GLOBAL_DEPENDENCIES)),$^,$(if $?,$?,$^)) -- $(SRC_QSTR_PREPROCESSOR) -- $(CPP) $(QSTR_GEN_EXTRA_CFLAGS) $(CFLAGS) + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py split compress $< $(HEADER_BUILD)/compress _ $(Q)$(TOUCH) $@ -$(QSTR_DEFS_COLLECTED): $(HEADER_BUILD)/qstr.split $(PY_SRC)/makeqstrdefs.py +$(HEADER_BUILD)/compressed.collected: $(HEADER_BUILD)/compressed.split $(STEPECHO) "GEN $@" - $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py cat - $(HEADER_BUILD)/qstr $(QSTR_DEFS_COLLECTED) + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdefs.py cat compress _ $(HEADER_BUILD)/compress $@ # $(sort $(var)) removes duplicates # @@ -117,8 +150,6 @@ $(OBJ_DIRS): $(HEADER_BUILD): $(Q)$(MKDIR) -p $@ - $(MKDIR) -p $@ - ifneq ($(MICROPY_MPYCROSS_DEPENDENCY),) # to automatically build mpy-cross, if needed $(MICROPY_MPYCROSS_DEPENDENCY): @@ -135,7 +166,7 @@ endif ifneq ($(FROZEN_MANIFEST),) # to build frozen_content.c from a manifest -$(BUILD)/frozen_content.c: FORCE $(FROZEN_MANIFEST) $(BUILD)/genhdr/qstrdefs.generated.h | $(MICROPY_MPYCROSS_DEPENDENCY) $(TOP)/tools/makemanifest.py +$(BUILD)/frozen_content.c: $(BUILD)/genhdr/qstrdefs.generated.h $(FROZEN_MANIFEST) | $(MICROPY_MPYCROSS_DEPENDENCY) $(Q)$(MAKE_MANIFEST) -o $@ -v "MPY_DIR=$(TOP)" -v "MPY_LIB_DIR=$(MPY_LIB_DIR)" -v "PORT_DIR=$(shell pwd)" -v "BOARD_DIR=$(BOARD_DIR)" -b "$(BUILD)" $(if $(MPY_CROSS_FLAGS),-f"$(MPY_CROSS_FLAGS)",) --mpy-tool-flags="$(MPY_TOOL_FLAGS)" $(FROZEN_MANIFEST) endif @@ -204,7 +235,9 @@ print-def: @$(CC) -E -Wp,-dM __empty__.c @$(RM) -f __empty__.c -tags: - ctags -e -R $(TOP) - -include $(OBJ:.o=.P) + +# Print out the value of a make variable. +# https://stackoverflow.com/questions/16467718/how-to-print-out-a-variable-in-makefile +print-%: + @echo $* = $($*) diff --git a/py/modarray.c b/py/modarray.c index daae34662b7c8..cfed0fbb59c4f 100644 --- a/py/modarray.c +++ b/py/modarray.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,6 +40,6 @@ const mp_obj_module_t mp_module_array = { .globals = (mp_obj_dict_t *)&mp_module_array_globals, }; -MP_REGISTER_MODULE(MP_QSTR_array, mp_module_array, MICROPY_PY_ARRAY); +MP_REGISTER_MODULE(MP_QSTR_array, mp_module_array); #endif diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 072ba8675fec9..870b19d7b283b 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -190,6 +190,7 @@ STATIC mp_obj_t mp_builtin_dir(size_t n_args, const mp_obj_t *args) { // Implemented by probing all possible qstrs with mp_load_method_maybe size_t nqstr = QSTR_TOTAL(); for (size_t i = MP_QSTR_ + 1; i < nqstr; ++i) { + // CIRCUITPY changes #6539 mp_obj_t dest[2] = {}; mp_load_method_protected(args[0], i, dest, true); if (dest[0] != MP_OBJ_NULL) { @@ -484,13 +485,13 @@ STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) { return o_in; } + #if !MICROPY_PY_BUILTINS_ROUND_INT + mp_raise_NotImplementedError(NULL); + #else mp_int_t num_dig = mp_obj_get_int(args[1]); if (num_dig >= 0) { return o_in; } - #if !MICROPY_PY_BUILTINS_ROUND_INT - mp_raise_NotImplementedError(NULL); - #else mp_obj_t mult = mp_binary_op(MP_BINARY_OP_POWER, MP_OBJ_NEW_SMALL_INT(10), MP_OBJ_NEW_SMALL_INT(-num_dig)); mp_obj_t half_mult = mp_binary_op(MP_BINARY_OP_FLOOR_DIVIDE, mult, MP_OBJ_NEW_SMALL_INT(2)); @@ -735,6 +736,9 @@ STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = { #endif { MP_ROM_QSTR(MP_QSTR_next), MP_ROM_PTR(&mp_builtin_next_obj) }, { MP_ROM_QSTR(MP_QSTR_oct), MP_ROM_PTR(&mp_builtin_oct_obj) }, + #if MICROPY_PY_IO + { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_ord), MP_ROM_PTR(&mp_builtin_ord_obj) }, { MP_ROM_QSTR(MP_QSTR_pow), MP_ROM_PTR(&mp_builtin_pow_obj) }, { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&mp_builtin_print_obj) }, @@ -794,3 +798,5 @@ const mp_obj_module_t mp_module_builtins = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&mp_module_builtins_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_builtins, mp_module_builtins); diff --git a/py/modcmath.c b/py/modcmath.c index a361ab53b497d..1418362ad9b1e 100644 --- a/py/modcmath.c +++ b/py/modcmath.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -149,4 +149,6 @@ const mp_obj_module_t mp_module_cmath = { .globals = (mp_obj_dict_t *)&mp_module_cmath_globals, }; -#endif // MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_CMATH +MP_REGISTER_MODULE(MP_QSTR_cmath, mp_module_cmath); + +#endif // MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_BUILTINS_COMPLEX && MICROPY_PY_CMATH diff --git a/py/modcollections.c b/py/modcollections.c index 235745f5843d9..a56fe069eaa77 100644 --- a/py/modcollections.c +++ b/py/modcollections.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -46,4 +46,6 @@ const mp_obj_module_t mp_module_collections = { .globals = (mp_obj_dict_t *)&mp_module_collections_globals, }; +MP_REGISTER_MODULE(MP_QSTR_collections, mp_module_collections); + #endif // MICROPY_PY_COLLECTIONS diff --git a/py/modgc.c b/py/modgc.c index e655cfa93e010..c11bcaecd7ddf 100644 --- a/py/modgc.c +++ b/py/modgc.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -115,4 +115,6 @@ const mp_obj_module_t mp_module_gc = { .globals = (mp_obj_dict_t *)&mp_module_gc_globals, }; +MP_REGISTER_MODULE(MP_QSTR_gc, mp_module_gc); + #endif diff --git a/py/modio.c b/py/modio.c index 819a9976a056a..836d04fb11834 100644 --- a/py/modio.c +++ b/py/modio.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -125,8 +125,7 @@ typedef struct _mp_obj_bufwriter_t { STATIC mp_obj_t bufwriter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, 2, false); size_t alloc = mp_obj_get_int(args[1]); - mp_obj_bufwriter_t *o = m_new_obj_var(mp_obj_bufwriter_t, byte, alloc); - o->base.type = type; + mp_obj_bufwriter_t *o = mp_obj_malloc_var(mp_obj_bufwriter_t, byte, alloc, type); o->stream = args[0]; o->alloc = alloc; o->len = 0; @@ -246,4 +245,6 @@ const mp_obj_module_t mp_module_io = { .globals = (mp_obj_dict_t *)&mp_module_io_globals, }; +MP_REGISTER_MODULE(MP_QSTR_uio, mp_module_io); + #endif diff --git a/py/modmath.c b/py/modmath.c index bf27e68eafda5..0567e5dd94696 100644 --- a/py/modmath.c +++ b/py/modmath.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * Copyright (c) 2013-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -373,6 +373,11 @@ STATIC const mp_rom_map_elem_t mp_module_math_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_math) }, { MP_ROM_QSTR(MP_QSTR_e), mp_const_float_e }, { MP_ROM_QSTR(MP_QSTR_pi), mp_const_float_pi }, + #if MICROPY_PY_MATH_CONSTANTS + { MP_ROM_QSTR(MP_QSTR_tau), mp_const_float_tau }, + { MP_ROM_QSTR(MP_QSTR_inf), mp_const_float_inf }, + { MP_ROM_QSTR(MP_QSTR_nan), mp_const_float_nan }, + #endif { MP_ROM_QSTR(MP_QSTR_sqrt), MP_ROM_PTR(&mp_math_sqrt_obj) }, { MP_ROM_QSTR(MP_QSTR_pow), MP_ROM_PTR(&mp_math_pow_obj) }, { MP_ROM_QSTR(MP_QSTR_exp), MP_ROM_PTR(&mp_math_exp_obj) }, @@ -432,4 +437,6 @@ const mp_obj_module_t mp_module_math = { .globals = (mp_obj_dict_t *)&mp_module_math_globals, }; +MP_REGISTER_MODULE(MP_QSTR_math, mp_module_math); + #endif // MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_MATH diff --git a/py/modmicropython.c b/py/modmicropython.c index 42c84e5292211..ee4d57d94ba93 100644 --- a/py/modmicropython.c +++ b/py/modmicropython.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -211,3 +211,5 @@ const mp_obj_module_t mp_module_micropython = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&mp_module_micropython_globals, }; + +MP_REGISTER_MODULE(MP_QSTR_micropython, mp_module_micropython); diff --git a/py/modstruct.c b/py/modstruct.c index 17dfc548ab372..a2dfa91655adf 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -33,6 +33,7 @@ #include "py/objtuple.h" #include "py/binary.h" #include "py/parsenum.h" + #include "supervisor/shared/translate/translate.h" #if MICROPY_PY_STRUCT @@ -282,4 +283,6 @@ const mp_obj_module_t mp_module_ustruct = { .globals = (mp_obj_dict_t *)&mp_module_struct_globals, }; +MP_REGISTER_MODULE(MP_QSTR_struct, mp_module_ustruct); + #endif diff --git a/py/modsys.c b/py/modsys.c index 0ec5de1645c11..63fb654f05a2c 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -27,6 +27,7 @@ #include "py/builtin.h" #include "py/objlist.h" +#include "py/objmodule.h" #include "py/objtuple.h" #include "py/objstr.h" #include "py/objint.h" @@ -35,6 +36,8 @@ #include "py/smallint.h" #include "py/runtime.h" #include "py/persistentcode.h" +#include "extmod/moduplatform.h" +#include "genhdr/mpversion.h" #if MICROPY_PY_SYS_SETTRACE #include "py/objmodule.h" @@ -84,7 +87,7 @@ STATIC const qstr impl_fields[] = { MP_QSTR_name, MP_QSTR_version, #if MICROPY_PERSISTENT_CODE_LOAD - MP_QSTR_mpy, + MP_QSTR__mpy, #endif }; STATIC MP_DEFINE_ATTRTUPLE( @@ -120,6 +123,25 @@ STATIC mp_obj_t mp_sys_exit(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit); +STATIC mp_obj_t mp_sys_print_exception(size_t n_args, const mp_obj_t *args) { + #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES + void *stream_obj = &mp_sys_stdout_obj; + if (n_args > 1) { + mp_get_stream_raise(args[1], MP_STREAM_OP_WRITE); + stream_obj = MP_OBJ_TO_PTR(args[1]); + } + + mp_print_t print = {stream_obj, mp_stream_write_adaptor}; + mp_obj_print_exception(&print, args[0]); + #else + (void)n_args; + mp_obj_print_exception(&mp_plat_print, args[0]); + #endif + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception); + #if MICROPY_PY_SYS_EXC_INFO STATIC mp_obj_t mp_sys_exc_info(void) { mp_obj_t cur_exc = MP_OBJ_FROM_PTR(MP_STATE_VM(cur_exception)); @@ -165,6 +187,25 @@ STATIC mp_obj_t mp_sys_settrace(mp_obj_t obj) { MP_DEFINE_CONST_FUN_OBJ_1(mp_sys_settrace_obj, mp_sys_settrace); #endif // MICROPY_PY_SYS_SETTRACE +#if MICROPY_PY_SYS_ATTR_DELEGATION +STATIC const uint16_t sys_mutable_keys[] = { + #if MICROPY_PY_SYS_PS1_PS2 + MP_QSTR_ps1, + MP_QSTR_ps2, + #endif + #if MICROPY_PY_SYS_TRACEBACKLIMIT + MP_QSTR_tracebacklimit, + #endif + MP_QSTRnull, +}; + +STATIC void mp_module_sys_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + MP_STATIC_ASSERT(MP_ARRAY_SIZE(sys_mutable_keys) == MP_SYS_MUTABLE_NUM + 1); + MP_STATIC_ASSERT(MP_ARRAY_SIZE(MP_STATE_VM(sys_mutable)) == MP_SYS_MUTABLE_NUM); + mp_module_generic_attr(attr, dest, sys_mutable_keys, MP_STATE_VM(sys_mutable)); +} +#endif + STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sys) }, @@ -223,9 +264,15 @@ STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = { * Extensions to CPython */ + { MP_ROM_QSTR(MP_QSTR_print_exception), MP_ROM_PTR(&mp_sys_print_exception_obj) }, #if MICROPY_PY_SYS_ATEXIT { MP_ROM_QSTR(MP_QSTR_atexit), MP_ROM_PTR(&mp_sys_atexit_obj) }, #endif + + #if MICROPY_PY_SYS_ATTR_DELEGATION + // Delegation of attr lookup. + MP_MODULE_ATTR_DELEGATION_ENTRY(&mp_module_sys_attr), + #endif }; STATIC MP_DEFINE_CONST_DICT(mp_module_sys_globals, mp_module_sys_globals_table); @@ -235,4 +282,6 @@ const mp_obj_module_t mp_module_sys = { .globals = (mp_obj_dict_t *)&mp_module_sys_globals, }; +MP_REGISTER_MODULE(MP_QSTR_usys, mp_module_sys); + #endif diff --git a/py/modthread.c b/py/modthread.c index a3960cddcb1e2..bad94fbf2f088 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd + * Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,6 @@ #include "py/runtime.h" #include "py/stackctrl.h" -#include "supervisor/shared/translate/translate.h" - #if MICROPY_PY_THREAD #include "py/mpthread.h" @@ -56,8 +54,7 @@ typedef struct _mp_obj_thread_lock_t { } mp_obj_thread_lock_t; STATIC mp_obj_thread_lock_t *mp_obj_new_thread_lock(void) { - mp_obj_thread_lock_t *self = m_new_obj(mp_obj_thread_lock_t); - self->base.type = &mp_type_thread_lock; + mp_obj_thread_lock_t *self = mp_obj_malloc(mp_obj_thread_lock_t, &mp_type_thread_lock); mp_thread_mutex_init(&self->mutex); self->locked = false; return self; @@ -303,4 +300,6 @@ const mp_obj_module_t mp_module_thread = { .globals = (mp_obj_dict_t *)&mp_module_thread_globals, }; +MP_REGISTER_MODULE(MP_QSTR__thread, mp_module_thread); + #endif // MICROPY_PY_THREAD diff --git a/py/moduerrno.c b/py/moduerrno.c index 0ac0503ccc2c2..cf3cbe064f581 100644 --- a/py/moduerrno.c +++ b/py/moduerrno.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -105,7 +105,11 @@ const mp_obj_module_t mp_module_uerrno = { .globals = (mp_obj_dict_t *)&mp_module_uerrno_globals, }; -MP_REGISTER_MODULE(MP_QSTR_errno, mp_module_uerrno, MICROPY_PY_UERRNO); +#if defined(MICROPY_UNIX_COVERAGE) +MP_REGISTER_MODULE(MP_QSTR_uerrno, mp_module_uerrno); +#else +MP_REGISTER_MODULE(MP_QSTR_errno, mp_module_uerrno); +#endif qstr mp_errno_to_str(mp_obj_t errno_val) { // Otherwise, return the Exxxx string for that error code diff --git a/py/mpconfig.h b/py/mpconfig.h index d3842afbe729a..0c4b924ef9b0c 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,6 +26,29 @@ #ifndef MICROPY_INCLUDED_PY_MPCONFIG_H #define MICROPY_INCLUDED_PY_MPCONFIG_H +// In CircuitPython, version info is in genhdr/mpversion.h. +#if CIRCUITPY +#include "genhdr/mpversion.h" +#else +// Current version of MicroPython +#define MICROPY_VERSION_MAJOR 1 +#define MICROPY_VERSION_MINOR 19 +#define MICROPY_VERSION_MICRO 1 + +// Combined version as a 32-bit number for convenience +#define MICROPY_VERSION ( \ + MICROPY_VERSION_MAJOR << 16 \ + | MICROPY_VERSION_MINOR << 8 \ + | MICROPY_VERSION_MICRO) + +// String version +#define MICROPY_VERSION_STRING \ + MP_STRINGIFY(MICROPY_VERSION_MAJOR) "." \ + MP_STRINGIFY(MICROPY_VERSION_MINOR) "." \ + MP_STRINGIFY(MICROPY_VERSION_MICRO) +#endif + + // This file contains default configuration settings for MicroPython. // You can override any of the options below using mpconfigport.h file // located in a directory of your port. @@ -180,12 +203,6 @@ #define MICROPY_ALLOC_QSTR_CHUNK_INIT (128) #endif -// Max number of entries in newly allocated QSTR pools. Smaller numbers may make QSTR lookups -// slightly slower but reduce the waste of unused spots. -#ifndef MICROPY_QSTR_POOL_MAX_ENTRIES -#define MICROPY_QSTR_POOL_MAX_ENTRIES (64) -#endif - // Initial amount for lexer indentation level #ifndef MICROPY_ALLOC_LEXER_INDENT_INIT #define MICROPY_ALLOC_LEXER_INDENT_INIT (10) @@ -298,14 +315,6 @@ #define alloca(x) m_malloc(x) #endif -// Number of atb indices to cache. Allocations of fewer blocks will be faster -// because the search will be accelerated by the index cache. This only applies -// to short lived allocations because we assume the long lived allocations are -// contiguous. -#ifndef MICROPY_ATB_INDICES -#define MICROPY_ATB_INDICES (8) -#endif - /*****************************************************************************/ /* MicroPython emitters */ @@ -330,6 +339,14 @@ #define MICROPY_PERSISTENT_CODE (MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE || MICROPY_MODULE_FROZEN_MPY) #endif +// Whether bytecode uses a qstr_table to map internal qstr indices in the bytecode +// to global qstr values in the runtime (behaviour when feature is enabled), or +// just stores global qstr values directly in the bytecode. This must be enabled +// if MICROPY_PERSISTENT_CODE is enabled. +#ifndef MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE +#define MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE (MICROPY_PERSISTENT_CODE) +#endif + // Whether to emit x64 native code #ifndef MICROPY_EMIT_X64 #define MICROPY_EMIT_X64 (0) @@ -355,11 +372,6 @@ #define MICROPY_EMIT_INLINE_THUMB (0) #endif -// Whether to enable ARMv7-M instruction support in the Thumb2 inline assembler -#ifndef MICROPY_EMIT_INLINE_THUMB_ARMV7M -#define MICROPY_EMIT_INLINE_THUMB_ARMV7M (1) -#endif - // Whether to enable float support in the Thumb2 inline assembler #ifndef MICROPY_EMIT_INLINE_THUMB_FLOAT #define MICROPY_EMIT_INLINE_THUMB_FLOAT (1) @@ -388,8 +400,10 @@ // Convenience definition for whether any native emitter is enabled #define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_X86 || MICROPY_EMIT_THUMB || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA || MICROPY_EMIT_XTENSAWIN) -// Select prelude-as-bytes-object for certain emitters -#define MICROPY_EMIT_NATIVE_PRELUDE_AS_BYTES_OBJ (MICROPY_EMIT_XTENSAWIN) +// Some architectures cannot read byte-wise from executable memory. In this case +// the prelude for a native function (which usually sits after the machine code) +// must be separated and placed somewhere where it can be read byte-wise. +#define MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE (MICROPY_EMIT_XTENSAWIN) // Convenience definition for whether any inline assembler emitter is enabled #define MICROPY_EMIT_INLINE_ASM (MICROPY_EMIT_INLINE_THUMB || MICROPY_EMIT_INLINE_XTENSA) @@ -423,18 +437,17 @@ #define MICROPY_DYNAMIC_COMPILER (0) #endif -// Configure dynamic compiler macros -#if MICROPY_DYNAMIC_COMPILER -#define MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC (mp_dynamic_compiler.py_builtins_str_unicode) -#else -#define MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC MICROPY_PY_BUILTINS_STR_UNICODE -#endif - // Whether to enable constant folding; eg 1+2 rewritten as 3 #ifndef MICROPY_COMP_CONST_FOLDING #define MICROPY_COMP_CONST_FOLDING (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif +// Whether to compile constant tuples immediately to their respective objects; eg (1, True) +// Otherwise the tuple will be built at runtime +#ifndef MICROPY_COMP_CONST_TUPLE +#define MICROPY_COMP_CONST_TUPLE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) +#endif + // Whether to enable optimisations for constant literals, eg OrderedDict #ifndef MICROPY_COMP_CONST_LITERAL #define MICROPY_COMP_CONST_LITERAL (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) @@ -468,11 +481,6 @@ #define MICROPY_COMP_RETURN_IF_EXPR (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Whether to include parsing of f-string literals -#ifndef MICROPY_COMP_FSTRING_LITERAL -#define MICROPY_COMP_FSTRING_LITERAL (1) -#endif - /*****************************************************************************/ /* Internal debugging stuff */ @@ -513,6 +521,7 @@ #define MICROPY_DEBUG_VM_STACK_OVERFLOW (0) #endif +// CIRCUITPY // Whether to enable extra instrumentation for valgrind #ifndef MICROPY_DEBUG_VALGRIND #define MICROPY_DEBUG_VALGRIND (0) @@ -530,6 +539,7 @@ #define MICROPY_OPT_COMPUTED_GOTO (0) #endif +// CIRCUITPY // Whether to save trade flash space for speed in MICROPY_OPT_COMPUTED_GOTO. // Costs about 3% speed, saves about 1500 bytes space. In addition to the assumptions // of MICROPY_OPT_COMPUTED_GOTO, also assumes that mp_execute_bytecode is less than @@ -595,6 +605,7 @@ #define MICROPY_HAS_FILE_READER (MICROPY_READER_POSIX || MICROPY_READER_VFS) #endif +// CIRCUITPY // Number of VFS mounts to persist across soft-reset. #ifndef MICROPY_FATFS_NUM_PERSISTENT #define MICROPY_FATFS_NUM_PERSISTENT (0) @@ -632,6 +643,11 @@ #define MICROPY_GC_HOOK_LOOP #endif +// Whether to provide m_tracked_calloc, m_tracked_free functions +#ifndef MICROPY_TRACKED_ALLOC +#define MICROPY_TRACKED_ALLOC (0) +#endif + // Whether to enable finalisers in the garbage collector (ie call __del__) #ifndef MICROPY_ENABLE_FINALISER #define MICROPY_ENABLE_FINALISER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -654,11 +670,6 @@ #define MICROPY_STACK_CHECK (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Whether to measure maximum stack excursion -#ifndef MICROPY_MAX_STACK_USAGE -#define MICROPY_MAX_STACK_USAGE (0) -#endif - // Whether to have an emergency exception buffer #ifndef MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0) @@ -773,11 +784,13 @@ typedef long long mp_longint_impl_t; #define MICROPY_WARNINGS (0) #endif +// CIRCUITPY // Whether to support chained exceptions #ifndef MICROPY_CPYTHON_EXCEPTION_CHAIN #define MICROPY_CPYTHON_EXCEPTION_CHAIN (0) #endif +// CIRCUITPY // Whether the statically allocated GeneratorExit exception may be const #ifndef MICROPY_CONST_GENERATOREXIT_OBJ #define MICROPY_CONST_GENERATOREXIT_OBJ (!MICROPY_CPYTHON_EXCEPTION_CHAIN) @@ -854,6 +867,12 @@ typedef double mp_float_t; #define MICROPY_STREAMS_POSIX_API (0) #endif +// Whether modules can use MP_MODULE_ATTR_DELEGATION_ENTRY() to delegate failed +// attribute lookups. +#ifndef MICROPY_MODULE_ATTR_DELEGATION +#define MICROPY_MODULE_ATTR_DELEGATION (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether to call __init__ when importing builtin modules for the first time #ifndef MICROPY_MODULE_BUILTIN_INIT #define MICROPY_MODULE_BUILTIN_INIT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -919,6 +938,11 @@ typedef double mp_float_t; #define MICROPY_ENABLE_SCHEDULER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif +// Whether the scheduler supports scheduling static nodes with C callbacks +#ifndef MICROPY_SCHEDULER_STATIC_NODES +#define MICROPY_SCHEDULER_STATIC_NODES (0) +#endif + // Maximum number of entries in the scheduler #ifndef MICROPY_SCHEDULER_DEPTH #define MICROPY_SCHEDULER_DEPTH (4) @@ -939,11 +963,6 @@ typedef double mp_float_t; #define MICROPY_VFS_FAT (0) #endif -// 1 when building C code for native mpy files. 0 otherwise. -#ifndef MICROPY_ENABLE_DYNRUNTIME -#define MICROPY_ENABLE_DYNRUNTIME (0) -#endif - /*****************************************************************************/ /* Fine control over Python builtins, classes, modules, etc */ @@ -1277,6 +1296,11 @@ typedef double mp_float_t; #define MICROPY_PY_MATH (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif +// Whether to provide all math module constants (Python 3.5+), or just pi and e. +#ifndef MICROPY_PY_MATH_CONSTANTS +#define MICROPY_PY_MATH_CONSTANTS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether to provide special math functions: math.{erf,erfc,gamma,lgamma} #ifndef MICROPY_PY_MATH_SPECIAL_FUNCTIONS #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -1393,6 +1417,11 @@ typedef double mp_float_t; #define MICROPY_PY_SYS_ATEXIT (0) #endif +// Whether to provide sys.{ps1,ps2} mutable attributes, to control REPL prompts +#ifndef MICROPY_PY_SYS_PS1_PS2 +#define MICROPY_PY_SYS_PS1_PS2 (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether to provide "sys.settrace" function #ifndef MICROPY_PY_SYS_SETTRACE #define MICROPY_PY_SYS_SETTRACE (0) @@ -1414,6 +1443,17 @@ typedef double mp_float_t; #define MICROPY_PY_SYS_STDIO_BUFFER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif +// Whether to provide sys.tracebacklimit mutable attribute +#ifndef MICROPY_PY_SYS_TRACEBACKLIMIT +#define MICROPY_PY_SYS_TRACEBACKLIMIT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) +#endif + +// Whether the sys module supports attribute delegation +// This is enabled automatically when needed by other features +#ifndef MICROPY_PY_SYS_ATTR_DELEGATION +#define MICROPY_PY_SYS_ATTR_DELEGATION (MICROPY_PY_SYS_PS1_PS2 || MICROPY_PY_SYS_TRACEBACKLIMIT) +#endif + // Whether to provide "uerrno" module #ifndef MICROPY_PY_UERRNO #define MICROPY_PY_UERRNO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -1498,6 +1538,14 @@ typedef double mp_float_t; #define MICROPY_PY_UJSON_SEPARATORS (1) #endif +#ifndef MICROPY_PY_UOS +#define MICROPY_PY_UOS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + +#ifndef MICROPY_PY_UOS_STATVFS +#define MICROPY_PY_UOS_STATVFS (MICROPY_PY_UOS) +#endif + #ifndef CIRCUITPY_ULAB #define CIRCUITPY_ULAB (0) #endif @@ -1596,6 +1644,11 @@ typedef double mp_float_t; #define MICROPY_PY_MACHINE_I2C (0) #endif +// Whether the low-level I2C transfer function supports a separate write as the first transfer +#ifndef MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 +#define MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 (0) +#endif + // Whether to provide the "machine.SoftI2C" class #ifndef MICROPY_PY_MACHINE_SOFTI2C #define MICROPY_PY_MACHINE_SOFTI2C (0) @@ -1610,6 +1663,11 @@ typedef double mp_float_t; #define MICROPY_PY_MACHINE_SOFTSPI (0) #endif +// The default backlog value for socket.listen(backlog) +#ifndef MICROPY_PY_USOCKET_LISTEN_BACKLOG_DEFAULT +#define MICROPY_PY_USOCKET_LISTEN_BACKLOG_DEFAULT (2) +#endif + #ifndef MICROPY_PY_USSL #define MICROPY_PY_USSL (0) #endif @@ -1654,11 +1712,6 @@ typedef double mp_float_t; #define MICROPY_PORT_EXTRA_BUILTINS #endif -// Additional builtin module definitions - see objmodule.c:mp_builtin_module_table for format. -#ifndef MICROPY_PORT_BUILTIN_MODULES -#define MICROPY_PORT_BUILTIN_MODULES -#endif - // Additional constant definitions for the compiler - see compile.c:mp_constants_table. #ifndef MICROPY_PORT_CONSTANTS #define MICROPY_PORT_CONSTANTS @@ -1719,6 +1772,20 @@ typedef double mp_float_t; #define MICROPY_OBJ_BASE_ALIGNMENT #endif +// String used for the banner, and sys.version additional information +#ifndef MICROPY_BANNER_NAME_AND_VERSION +#define MICROPY_BANNER_NAME_AND_VERSION "MicroPython " MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE +#endif + +// String used for the second part of the banner, and sys.implementation._machine +#ifndef MICROPY_BANNER_MACHINE +#ifdef MICROPY_HW_BOARD_NAME +#define MICROPY_BANNER_MACHINE MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME +#else +#define MICROPY_BANNER_MACHINE MICROPY_PY_SYS_PLATFORM " [" MICROPY_PLATFORM_COMPILER "] version" +#endif +#endif + // On embedded platforms, these will typically enable/disable irqs. #ifndef MICROPY_BEGIN_ATOMIC_SECTION #define MICROPY_BEGIN_ATOMIC_SECTION() (0) diff --git a/py/mperrno.h b/py/mperrno.h index f9819169e07c0..4c9af57ee8772 100644 --- a/py/mperrno.h +++ b/py/mperrno.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/mphal.h b/py/mphal.h index 13aae19a7121c..0d4b1224e5cec 100644 --- a/py/mphal.h +++ b/py/mphal.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2015 Damien P. George + * Copyright (c) 2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/mpprint.c b/py/mpprint.c index df73587449e77..527acd471d635 100644 --- a/py/mpprint.c +++ b/py/mpprint.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2015 Damien P. George + * Copyright (c) 2013-2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/mpprint.h b/py/mpprint.h index 616f21a91e4f3..fbfa3d9914b79 100644 --- a/py/mpprint.h +++ b/py/mpprint.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/mpstate.c b/py/mpstate.c index b3957cc09a7b9..32f1d60a598e2 100644 --- a/py/mpstate.c +++ b/py/mpstate.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * Copyright (c) 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/mpstate.h b/py/mpstate.h index cf1711b8ad061..6871e2b40a409 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -36,15 +36,31 @@ #include "py/objlist.h" #include "py/objexcept.h" +// #if CIRCUITPY +// #error CIRCUITPY is TRUE in mpstate.h. +// #else +// #error CIRCUITPY is **FALSE** in mpstate.h +// #endif + // This file contains structures defining the state of the MicroPython // memory system, runtime and virtual machine. The state is a global // variable, but in the future it is hoped that the state can become local. +enum { + #if MICROPY_PY_SYS_PS1_PS2 + MP_SYS_MUTABLE_PS1, + MP_SYS_MUTABLE_PS2, + #endif + #if MICROPY_PY_SYS_TRACEBACKLIMIT + MP_SYS_MUTABLE_TRACEBACKLIMIT, + #endif + MP_SYS_MUTABLE_NUM, +}; + // This structure contains dynamic configuration for the compiler. #if MICROPY_DYNAMIC_COMPILER typedef struct mp_dynamic_compiler_t { uint8_t small_int_bits; // must be <= host small_int_bits - bool py_builtins_str_unicode; uint8_t native_arch; uint8_t nlr_buf_num_regs; } mp_dynamic_compiler_t; @@ -77,22 +93,19 @@ typedef struct _mp_state_mem_t { byte *gc_pool_start; byte *gc_pool_end; - void *gc_lowest_long_lived_ptr; - int gc_stack_overflow; MICROPY_GC_STACK_ENTRY_TYPE gc_stack[MICROPY_ALLOC_GC_STACK_SIZE]; - // This variable controls auto garbage collection. If set to false then the + // This variable controls auto garbage collection. If set to 0 then the // GC won't automatically run when gc_alloc can't find enough blocks. But // you can still allocate/free memory and also explicitly call gc_collect. - bool gc_auto_collect_enabled; + uint16_t gc_auto_collect_enabled; #if MICROPY_GC_ALLOC_THRESHOLD size_t gc_alloc_amount; size_t gc_alloc_threshold; #endif - size_t gc_first_free_atb_index[MICROPY_ATB_INDICES]; size_t gc_last_free_atb_index; #if MICROPY_PY_GC_COLLECT_RETVAL @@ -104,6 +117,7 @@ typedef struct _mp_state_mem_t { mp_thread_mutex_t gc_mutex; #endif + // CIRCUITPY void **permanent_pointers; } mp_state_mem_t; @@ -173,6 +187,11 @@ typedef struct _mp_state_vm_t { // must be initialised after the call to mp_init. mp_obj_list_t mp_sys_path_obj; mp_obj_list_t mp_sys_argv_obj; + + #if MICROPY_PY_SYS_ATTR_DELEGATION + // Contains mutable sys attributes. + mp_obj_t sys_mutable[MP_SYS_MUTABLE_NUM]; + #endif #endif // dictionary for overridden builtins @@ -194,11 +213,23 @@ typedef struct _mp_state_vm_t { vstr_t *repl_line; #endif + #if MICROPY_PY_OS_DUPTERM + mp_obj_t dupterm_objs[MICROPY_PY_OS_DUPTERM]; + #endif + + #if MICROPY_PY_LWIP_SLIP + mp_obj_t lwip_slip_stream; + #endif + #if MICROPY_VFS struct _mp_vfs_mount_t *vfs_cur; struct _mp_vfs_mount_t *vfs_mount_table; #endif + #if MICROPY_PY_BLUETOOTH + mp_obj_t bluetooth; + #endif + // // END ROOT POINTER SECTION //////////////////////////////////////////////////////////// @@ -228,6 +259,16 @@ typedef struct _mp_state_vm_t { #if MICROPY_ENABLE_SCHEDULER volatile int16_t sched_state; + + #if MICROPY_SCHEDULER_STATIC_NODES + // These will usually point to statically allocated memory. They are not + // traced by the GC. They are assumed to be zero'd out before mp_init() is + // called (usually because this struct lives in the BSS). + struct _mp_sched_node_t *sched_head; + struct _mp_sched_node_t *sched_tail; + #endif + + // These index sched_queue. uint8_t sched_len; uint8_t sched_idx; #endif @@ -249,6 +290,7 @@ typedef struct _mp_state_thread_t { // Stack top at the start of program char *stack_top; + // CIRCUITPY #if MICROPY_MAX_STACK_USAGE char *stack_bottom; #endif diff --git a/py/mpthread.h b/py/mpthread.h index fa9e054e3d68a..e611ef4c1197e 100644 --- a/py/mpthread.h +++ b/py/mpthread.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd + * Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/mpz.c b/py/mpz.c index b52e05148a32d..3218d5f392199 100644 --- a/py/mpz.c +++ b/py/mpz.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/mpz.h b/py/mpz.h index 0fdcf52cff303..0de0b31f73c68 100644 --- a/py/mpz.h +++ b/py/mpz.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/nativeglue.c b/py/nativeglue.c index 29ca77b39efbf..0e9bbf54eb0e3 100644 --- a/py/nativeglue.c +++ b/py/nativeglue.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * Copyright (c) 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -301,9 +301,9 @@ const mp_fun_table_t mp_fun_table = { mp_unpack_ex, mp_delete_name, mp_delete_global, - mp_make_closure_from_raw_code, + mp_obj_new_closure, mp_arg_check_num_sig, - mp_setup_code_state, + mp_setup_code_state_native, mp_small_int_floor_divide, mp_small_int_modulo, mp_native_yield_from, @@ -346,4 +346,8 @@ const mp_fun_table_t mp_fun_table = { &mp_stream_write_obj, }; +#elif MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER + +const int mp_fun_table; + #endif // MICROPY_EMIT_NATIVE diff --git a/py/nativeglue.h b/py/nativeglue.h index e1f0be3f4fda3..5f7bfe01100ca 100644 --- a/py/nativeglue.h +++ b/py/nativeglue.h @@ -75,7 +75,7 @@ typedef enum { MP_F_UNPACK_EX, MP_F_DELETE_NAME, MP_F_DELETE_GLOBAL, - MP_F_MAKE_CLOSURE_FROM_RAW_CODE, + MP_F_NEW_CLOSURE, MP_F_ARG_CHECK_NUM_SIG, MP_F_SETUP_CODE_STATE, MP_F_SMALL_INT_FLOOR_DIVIDE, @@ -112,7 +112,7 @@ typedef struct _mp_fun_table_t { void (*set_store)(mp_obj_t self_in, mp_obj_t item); mp_obj_t (*list_append)(mp_obj_t self_in, mp_obj_t arg); mp_obj_t (*dict_store)(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); - mp_obj_t (*make_function_from_raw_code)(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args); + mp_obj_t (*make_function_from_raw_code)(const mp_raw_code_t *rc, const mp_module_context_t *cm, const mp_obj_t *def_args); mp_obj_t (*call_function_n_kw)(mp_obj_t fun_in, size_t n_args_kw, const mp_obj_t *args); mp_obj_t (*call_method_n_kw)(size_t n_args, size_t n_kw, const mp_obj_t *args); mp_obj_t (*call_method_n_kw_var)(bool have_self, size_t n_args_n_kw, const mp_obj_t *args); @@ -129,9 +129,9 @@ typedef struct _mp_fun_table_t { void (*unpack_ex)(mp_obj_t seq, size_t num, mp_obj_t *items); void (*delete_name)(qstr qst); void (*delete_global)(qstr qst); - mp_obj_t (*make_closure_from_raw_code)(const mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args); + mp_obj_t (*new_closure)(mp_obj_t fun, size_t n_closed_over, const mp_obj_t *closed); void (*arg_check_num_sig)(size_t n_args, size_t n_kw, uint32_t sig); - void (*setup_code_state)(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args); + void (*setup_code_state_native)(mp_code_state_native_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args); mp_int_t (*small_int_floor_divide)(mp_int_t num, mp_int_t denom); mp_int_t (*small_int_modulo)(mp_int_t dividend, mp_int_t divisor); bool (*yield_from)(mp_obj_t gen, mp_obj_t send_value, mp_obj_t *ret_value); @@ -173,6 +173,12 @@ typedef struct _mp_fun_table_t { const mp_obj_fun_builtin_var_t *stream_write_obj; } mp_fun_table_t; +#if (MICROPY_EMIT_NATIVE && !MICROPY_DYNAMIC_COMPILER) || MICROPY_ENABLE_DYNRUNTIME extern const mp_fun_table_t mp_fun_table; +#elif MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER +// In dynamic-compiler mode eliminate dependency on entries in mp_fun_table. +// This only needs to be an independent pointer, content doesn't matter. +extern const int mp_fun_table; +#endif #endif // MICROPY_INCLUDED_PY_NATIVEGLUE_H diff --git a/py/nlr.c b/py/nlr.c index 6dfd16219619b..32e2b42c305ce 100644 --- a/py/nlr.c +++ b/py/nlr.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * Copyright (c) 2013-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/nlr.h b/py/nlr.h index 1fb51f3585560..b7b016b1e67e5 100644 --- a/py/nlr.h +++ b/py/nlr.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -177,7 +177,7 @@ NORETURN void nlr_jump_fail(void *val); #if !MICROPY_NLR_SETJMP #define nlr_push(val) \ - assert(MP_STATE_THREAD(nlr_top) != val),nlr_push(val) + assert(MP_STATE_THREAD(nlr_top) != val), nlr_push(val) /* #define nlr_push(val) \ diff --git a/py/nlrsetjmp.c b/py/nlrsetjmp.c index a93595dc83db0..960dd86f52e54 100644 --- a/py/nlrsetjmp.c +++ b/py/nlrsetjmp.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * Copyright (c) 2013-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/nlrthumb.c b/py/nlrthumb.c index 4b20d30c6ef8f..1a1e83956e2c4 100644 --- a/py/nlrthumb.c +++ b/py/nlrthumb.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * Copyright (c) 2013-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,6 +36,7 @@ // For reference, arm/thumb callee save regs are: // r4-r11, r13=sp +// CIRCUITPY: added returns_twice __attribute__((naked, returns_twice)) unsigned int nlr_push(nlr_buf_t *nlr) { __asm volatile ( diff --git a/py/nlrx64.c b/py/nlrx64.c index f7e92608d27a9..df620ed9f7e29 100644 --- a/py/nlrx64.c +++ b/py/nlrx64.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * Copyright (c) 2013-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/nlrx86.c b/py/nlrx86.c index 0cc8b9e6da35c..a6c37a699833d 100644 --- a/py/nlrx86.c +++ b/py/nlrx86.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * Copyright (c) 2013-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/nlrxtensa.c b/py/nlrxtensa.c index 5aa767aaeb648..4123efd180278 100644 --- a/py/nlrxtensa.c +++ b/py/nlrxtensa.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Damien P. George + * Copyright (c) 2014-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/obj.c b/py/obj.c index c394656016b88..31d469770c47a 100644 --- a/py/obj.c +++ b/py/obj.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -43,6 +43,13 @@ #include "supervisor/shared/stack.h" #include "supervisor/shared/translate/translate.h" +// Allocates an object and also sets type, for mp_obj_malloc{,_var} macros. +void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type) { + mp_obj_base_t *base = (mp_obj_base_t *)m_malloc(num_bytes); + base->type = type; + return base; +} + const mp_obj_type_t *MICROPY_WRAP_MP_OBJ_GET_TYPE(mp_obj_get_type)(mp_const_obj_t o_in) { #if MICROPY_OBJ_IMMEDIATE_OBJS && MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A @@ -442,10 +449,10 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) { if (!mp_obj_get_float_maybe(arg, &val)) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE - mp_raise_TypeError_varg(MP_ERROR_TEXT("can't convert to %q"), MP_QSTR_float); + mp_raise_TypeError(MP_ERROR_TEXT("can't convert to float")); #else - mp_raise_TypeError_varg( - MP_ERROR_TEXT("can't convert %q to %q"), mp_obj_get_type_qstr(arg), MP_QSTR_float); + mp_raise_msg_varg(&mp_type_TypeError, + MP_ERROR_TEXT("can't convert %s to float"), mp_obj_get_type_str(arg)); #endif } @@ -512,7 +519,14 @@ void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { size_t seq_len; mp_obj_get_array(o, &seq_len, items); - mp_arg_validate_length(seq_len, len, mp_obj_get_type(o)->name); + if (seq_len != len) { + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + mp_raise_ValueError(MP_ERROR_TEXT("tuple/list has wrong length")); + #else + mp_raise_msg_varg(&mp_type_ValueError, + MP_ERROR_TEXT("requested length %d but object has length %d"), (int)len, (int)seq_len); + #endif + } } // is_slice determines whether the index is a slice index @@ -521,7 +535,13 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool if (mp_obj_is_small_int(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { - mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q, not %q"), MP_QSTR_index, MP_QSTR_int, mp_obj_get_type(index)->name); + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + mp_raise_TypeError(MP_ERROR_TEXT("indices must be integers")); + #else + mp_raise_msg_varg(&mp_type_TypeError, + MP_ERROR_TEXT("%q indices must be integers, not %s"), + type->name, mp_obj_get_type_str(index)); + #endif } if (i < 0) { diff --git a/py/obj.h b/py/obj.h index 92732b31dd897..d1874a8cd2cad 100644 --- a/py/obj.h +++ b/py/obj.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -107,8 +107,18 @@ static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { #if MICROPY_PY_BUILTINS_FLOAT #define mp_const_float_e MP_ROM_PTR(&mp_const_float_e_obj) #define mp_const_float_pi MP_ROM_PTR(&mp_const_float_pi_obj) +#if MICROPY_PY_MATH_CONSTANTS +#define mp_const_float_tau MP_ROM_PTR(&mp_const_float_tau_obj) +#define mp_const_float_inf MP_ROM_PTR(&mp_const_float_inf_obj) +#define mp_const_float_nan MP_ROM_PTR(&mp_const_float_nan_obj) +#endif extern const struct _mp_obj_float_t mp_const_float_e_obj; extern const struct _mp_obj_float_t mp_const_float_pi_obj; +#if MICROPY_PY_MATH_CONSTANTS +extern const struct _mp_obj_float_t mp_const_float_tau_obj; +extern const struct _mp_obj_float_t mp_const_float_inf_obj; +extern const struct _mp_obj_float_t mp_const_float_nan_obj; +#endif #define mp_obj_is_float(o) mp_obj_is_type((o), &mp_type_float) mp_float_t mp_obj_float_get(mp_obj_t self_in); @@ -142,8 +152,18 @@ static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { #if MICROPY_PY_BUILTINS_FLOAT #define mp_const_float_e MP_ROM_PTR(&mp_const_float_e_obj) #define mp_const_float_pi MP_ROM_PTR(&mp_const_float_pi_obj) +#if MICROPY_PY_MATH_CONSTANTS +#define mp_const_float_tau MP_ROM_PTR(&mp_const_float_tau_obj) +#define mp_const_float_inf MP_ROM_PTR(&mp_const_float_inf_obj) +#define mp_const_float_nan MP_ROM_PTR(&mp_const_float_nan_obj) +#endif extern const struct _mp_obj_float_t mp_const_float_e_obj; extern const struct _mp_obj_float_t mp_const_float_pi_obj; +#if MICROPY_PY_MATH_CONSTANTS +extern const struct _mp_obj_float_t mp_const_float_tau_obj; +extern const struct _mp_obj_float_t mp_const_float_inf_obj; +extern const struct _mp_obj_float_t mp_const_float_nan_obj; +#endif #define mp_obj_is_float(o) mp_obj_is_type((o), &mp_type_float) mp_float_t mp_obj_float_get(mp_obj_t self_in); @@ -165,6 +185,11 @@ static MP_INLINE bool mp_obj_is_small_int(mp_const_obj_t o) { #if MICROPY_PY_BUILTINS_FLOAT #define mp_const_float_e MP_ROM_PTR((mp_obj_t)(((0x402df854 & ~3) | 2) + 0x80800000)) #define mp_const_float_pi MP_ROM_PTR((mp_obj_t)(((0x40490fdb & ~3) | 2) + 0x80800000)) +#if MICROPY_PY_MATH_CONSTANTS +#define mp_const_float_tau MP_ROM_PTR((mp_obj_t)(((0x40c90fdb & ~3) | 2) + 0x80800000)) +#define mp_const_float_inf MP_ROM_PTR((mp_obj_t)(((0x7f800000 & ~3) | 2) + 0x80800000)) +#define mp_const_float_nan MP_ROM_PTR((mp_obj_t)(((0xffc00000 & ~3) | 2) + 0x80800000)) +#endif static MP_INLINE bool mp_obj_is_float(mp_const_obj_t o) { return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0xff800007) != 0x00000006; @@ -229,6 +254,11 @@ static MP_INLINE bool mp_obj_is_immediate_obj(mp_const_obj_t o) { #define mp_const_float_e {((mp_obj_t)((uint64_t)0x4005bf0a8b145769 + 0x8004000000000000))} #define mp_const_float_pi {((mp_obj_t)((uint64_t)0x400921fb54442d18 + 0x8004000000000000))} +#if MICROPY_PY_MATH_CONSTANTS +#define mp_const_float_tau {((mp_obj_t)((uint64_t)0x401921fb54442d18 + 0x8004000000000000))} +#define mp_const_float_inf {((mp_obj_t)((uint64_t)0x7ff0000000000000 + 0x8004000000000000))} +#define mp_const_float_nan {((mp_obj_t)((uint64_t)0xfff8000000000000 + 0x8004000000000000))} +#endif static MP_INLINE bool mp_obj_is_float(mp_const_obj_t o) { return ((uint64_t)(o) & 0xfffc000000000000) != 0; @@ -419,9 +449,10 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t; // Declare a module as a builtin, processed by makemoduledefs.py // param module_name: MP_QSTR_ // param obj_module: mp_obj_module_t instance -// param enabled_define: used as `#if (enabled_define) around entry` -#define MP_REGISTER_MODULE(module_name, obj_module, enabled_define) +#ifndef NO_QSTR +#define MP_REGISTER_MODULE(module_name, obj_module) +#endif // Underlying map/hash table implementation (not dict object or map function) @@ -437,11 +468,9 @@ typedef struct _mp_rom_map_elem_t { typedef struct _mp_map_t { size_t all_keys_are_qstrs : 1; - size_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered - size_t is_ordered : 1; // an ordered array - size_t scanning : 1; // true if we're in the middle of scanning linked dictionaries, - // e.g., make_dict_long_lived() - size_t used : (8 * sizeof(size_t) - 4); + size_t is_fixed : 1; // if set, table is fixed/read-only and can't be modified + size_t is_ordered : 1; // if set, table is an ordered array, not a hash map + size_t used : (8 * sizeof(size_t) - 3); size_t alloc; mp_map_elem_t *table; } mp_map_t; @@ -639,6 +668,7 @@ struct _mp_obj_full_type_t { mp_obj_base_t base; uint16_t flags; uint16_t name; + // A dict mapping qstrs to objects local methods/constants/etc. struct _mp_obj_dict_t *locals_dict; mp_make_new_fun_t make_new; mp_print_fun_t print; @@ -706,17 +736,24 @@ extern const mp_obj_type_t mp_type_zip; extern const mp_obj_type_t mp_type_array; extern const mp_obj_type_t mp_type_super; extern const mp_obj_type_t mp_type_gen_wrap; +#if MICROPY_EMIT_NATIVE extern const mp_obj_type_t mp_type_native_gen_wrap; +#endif extern const mp_obj_type_t mp_type_gen_instance; +// CIRCUITPY +#if MICROPY_PY_ASYNC_AWAIT +extern const mp_obj_type_t mp_type_coro_wrap; +#if MICROPY_EMIT_NATIVE +extern const mp_obj_type_t mp_type_native_coro_wrap; +#endif +extern const mp_obj_type_t mp_type_coro_instance; +#endif extern const mp_obj_type_t mp_type_fun_builtin_0; extern const mp_obj_type_t mp_type_fun_builtin_1; extern const mp_obj_type_t mp_type_fun_builtin_2; extern const mp_obj_type_t mp_type_fun_builtin_3; extern const mp_obj_type_t mp_type_fun_builtin_var; extern const mp_obj_type_t mp_type_fun_bc; -#if MICROPY_EMIT_NATIVE -extern const mp_obj_type_t mp_type_fun_native; -#endif extern const mp_obj_type_t mp_type_module; extern const mp_obj_type_t mp_type_staticmethod; extern const mp_obj_type_t mp_type_classmethod; @@ -801,6 +838,12 @@ extern const struct _mp_obj_exception_t mp_static_GeneratorExit_obj; // General API for objects +// Helper versions of m_new_obj when you need to immediately set base.type. +// Implementing this as a call rather than inline saves 8 bytes per usage. +#define mp_obj_malloc(struct_type, obj_type) ((struct_type *)mp_obj_malloc_helper(sizeof(struct_type), obj_type)) +#define mp_obj_malloc_var(struct_type, var_type, var_num, obj_type) ((struct_type *)mp_obj_malloc_helper(sizeof(struct_type) + sizeof(var_type) * (var_num), obj_type)) +void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); + // These macros are derived from more primitive ones and are used to // check for more specific object types. // Note: these are kept as macros because inline functions sometimes use much @@ -858,10 +901,6 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, const com #endif // Only use this string version from native MPY files with static error strings. mp_obj_t mp_obj_new_exception_msg_str(const mp_obj_type_t *exc_type, const char *msg); -mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table); -mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table); -mp_obj_t mp_obj_new_fun_viper(size_t n_args, const void *fun_data, mp_uint_t type_sig); -mp_obj_t mp_obj_new_fun_asm(size_t n_args, const void *fun_data, mp_uint_t type_sig); mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun, bool is_coroutine); mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed); mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items); @@ -1076,7 +1115,6 @@ typedef struct _mp_obj_fun_builtin_var_t { } mp_obj_fun_builtin_var_t; qstr mp_obj_fun_get_name(mp_const_obj_t fun); -qstr mp_obj_code_get_name(const byte *code_info); mp_obj_t mp_identity(mp_obj_t self); MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj); diff --git a/py/objarray.c b/py/objarray.c index c4a9e7cec4d3b..b8ea9992bb4b2 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -838,8 +838,7 @@ mp_obj_t mp_obj_new_bytearray_of_zeros(size_t n) { // Create bytearray which references specified memory area mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items) { - mp_obj_array_t *o = m_new_obj(mp_obj_array_t); - o->base.type = &mp_type_bytearray; + mp_obj_array_t *o = mp_obj_malloc(mp_obj_array_t, &mp_type_bytearray); o->typecode = BYTEARRAY_TYPECODE; o->free = 0; o->len = n; diff --git a/py/objarray.h b/py/objarray.h index a1bf6abfd1762..94c31c969386b 100644 --- a/py/objarray.h +++ b/py/objarray.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/py/objattrtuple.c b/py/objattrtuple.c index 7b664dd0fe247..c288727d48ce3 100644 --- a/py/objattrtuple.c +++ b/py/objattrtuple.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2015 Damien P. George + * Copyright (c) 2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -71,8 +71,7 @@ STATIC void mp_obj_attrtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } mp_obj_t mp_obj_new_attrtuple(const qstr *fields, size_t n, const mp_obj_t *items) { - mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n + 1); - o->base.type = &mp_type_attrtuple; + mp_obj_tuple_t *o = mp_obj_malloc_var(mp_obj_tuple_t, mp_obj_t, n + 1, &mp_type_attrtuple); o->len = n; for (size_t i = 0; i < n; i++) { o->items[i] = items[i]; diff --git a/py/objbool.c b/py/objbool.c index 13d10ffae366c..e450270fd9002 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objboundmeth.c b/py/objboundmeth.c index c460626c4ff23..edc37462dd031 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -111,8 +111,7 @@ STATIC const mp_obj_type_t mp_type_bound_meth = { }; mp_obj_t mp_obj_new_bound_meth(mp_obj_t meth, mp_obj_t self) { - mp_obj_bound_meth_t *o = m_new_obj(mp_obj_bound_meth_t); - o->base.type = &mp_type_bound_meth; + mp_obj_bound_meth_t *o = mp_obj_malloc(mp_obj_bound_meth_t, &mp_type_bound_meth); o->meth = meth; o->self = self; return MP_OBJ_FROM_PTR(o); diff --git a/py/objcell.c b/py/objcell.c index 2e15e6825aedf..2702ca5350599 100644 --- a/py/objcell.c +++ b/py/objcell.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -64,8 +64,7 @@ STATIC const mp_obj_type_t mp_type_cell = { }; mp_obj_t mp_obj_new_cell(mp_obj_t obj) { - mp_obj_cell_t *o = m_new_obj(mp_obj_cell_t); - o->base.type = &mp_type_cell; + mp_obj_cell_t *o = mp_obj_malloc(mp_obj_cell_t, &mp_type_cell); o->obj = obj; return MP_OBJ_FROM_PTR(o); } diff --git a/py/objclosure.c b/py/objclosure.c index f5dbb705ac74b..309dd2b826cc6 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -91,8 +91,7 @@ const mp_obj_type_t mp_type_closure = { }; mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed_over, const mp_obj_t *closed) { - mp_obj_closure_t *o = m_new_obj_var(mp_obj_closure_t, mp_obj_t, n_closed_over); - o->base.type = &mp_type_closure; + mp_obj_closure_t *o = mp_obj_malloc_var(mp_obj_closure_t, mp_obj_t, n_closed_over, &mp_type_closure); o->fun = fun; o->n_closed = n_closed_over; memcpy(o->closed, closed, n_closed_over * sizeof(mp_obj_t)); diff --git a/py/objcomplex.c b/py/objcomplex.c index 7f4fd621e6eaf..570f9f746f5ae 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -169,8 +169,7 @@ const mp_obj_type_t mp_type_complex = { }; mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag) { - mp_obj_complex_t *o = m_new_obj(mp_obj_complex_t); - o->base.type = &mp_type_complex; + mp_obj_complex_t *o = mp_obj_malloc(mp_obj_complex_t, &mp_type_complex); o->real = real; o->imag = imag; return MP_OBJ_FROM_PTR(o); diff --git a/py/objdeque.c b/py/objdeque.c index 59c4c709fcc2a..621b7b60b0f9a 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -59,8 +59,7 @@ STATIC mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, size_t mp_raise_ValueError(NULL); } - mp_obj_deque_t *o = m_new_obj(mp_obj_deque_t); - o->base.type = type; + mp_obj_deque_t *o = mp_obj_malloc(mp_obj_deque_t, type); o->alloc = maxlen + 1; o->i_get = o->i_put = 0; o->items = m_new0(mp_obj_t, o->alloc); diff --git a/py/objdict.c b/py/objdict.c index abe72e7839a88..e4e9711c603e3 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -584,8 +584,7 @@ STATIC const mp_obj_type_t mp_type_dict_view = { }; STATIC mp_obj_t mp_obj_new_dict_view(mp_obj_t dict, mp_dict_view_kind_t kind) { - mp_obj_dict_view_t *o = m_new_obj(mp_obj_dict_view_t); - o->base.type = &mp_type_dict_view; + mp_obj_dict_view_t *o = mp_obj_malloc(mp_obj_dict_view_t, &mp_type_dict_view); o->dict = dict; o->kind = kind; return MP_OBJ_FROM_PTR(o); diff --git a/py/objenumerate.c b/py/objenumerate.c index c18ac1dd8044a..2ef553adb5e36 100644 --- a/py/objenumerate.c +++ b/py/objenumerate.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -54,14 +54,12 @@ STATIC mp_obj_t enumerate_make_new(const mp_obj_type_t *type, size_t n_args, siz MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&arg_vals); // create enumerate object - mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t); - o->base.type = type; + mp_obj_enumerate_t *o = mp_obj_malloc(mp_obj_enumerate_t, type); o->iter = mp_getiter(arg_vals.iterable.u_obj, NULL); o->cur = arg_vals.start.u_int; #else - (void)n_kw; - mp_obj_enumerate_t *o = m_new_obj(mp_obj_enumerate_t); - o->base.type = type; + mp_arg_check_num(n_args, n_kw, 1, 2, false); + mp_obj_enumerate_t *o = mp_obj_malloc(mp_obj_enumerate_t, type); o->iter = mp_getiter(args[0], NULL); o->cur = n_args > 1 ? mp_obj_get_int(args[1]) : 0; #endif diff --git a/py/objexcept.c b/py/objexcept.c index e05c3ca8d7390..282740ae440b0 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2016 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2016 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -325,67 +325,56 @@ MP_DEFINE_EXCEPTION(KeyboardInterrupt, BaseException) MP_DEFINE_EXCEPTION(ReloadException, BaseException) MP_DEFINE_EXCEPTION(GeneratorExit, BaseException) MP_DEFINE_EXCEPTION(Exception, BaseException) - #if MICROPY_PY_ASYNC_AWAIT -MP_DEFINE_EXCEPTION(StopAsyncIteration, Exception) - #endif -MP_DEFINE_EXCEPTION(StopIteration, Exception) -MP_DEFINE_EXCEPTION(ArithmeticError, Exception) -// MP_DEFINE_EXCEPTION(FloatingPointError, ArithmeticError) -MP_DEFINE_EXCEPTION(OverflowError, ArithmeticError) -MP_DEFINE_EXCEPTION(ZeroDivisionError, ArithmeticError) -MP_DEFINE_EXCEPTION(AssertionError, Exception) -MP_DEFINE_EXCEPTION(AttributeError, Exception) -// MP_DEFINE_EXCEPTION(BufferError, Exception) -// MP_DEFINE_EXCEPTION(EnvironmentError, Exception) use OSError instead -MP_DEFINE_EXCEPTION(EOFError, Exception) -MP_DEFINE_EXCEPTION(ImportError, Exception) -// MP_DEFINE_EXCEPTION(IOError, Exception) use OSError instead -MP_DEFINE_EXCEPTION(LookupError, Exception) -MP_DEFINE_EXCEPTION(IndexError, LookupError) -MP_DEFINE_EXCEPTION(KeyError, LookupError) -MP_DEFINE_EXCEPTION(MemoryError, Exception) -MP_DEFINE_EXCEPTION(NameError, Exception) -/* - MP_DEFINE_EXCEPTION(UnboundLocalError, NameError) - */ -MP_DEFINE_EXCEPTION(OSError, Exception) -MP_DEFINE_EXCEPTION(TimeoutError, OSError) -MP_DEFINE_EXCEPTION(ConnectionError, OSError) -MP_DEFINE_EXCEPTION(BrokenPipeError, ConnectionError) -/* - MP_DEFINE_EXCEPTION(ConnectionAbortedError, ConnectionError) - MP_DEFINE_EXCEPTION(ConnectionRefusedError, ConnectionError) - MP_DEFINE_EXCEPTION(ConnectionResetError, ConnectionError) - */ -/* - MP_DEFINE_EXCEPTION(BlockingIOError, OSError) - MP_DEFINE_EXCEPTION(ChildProcessError, OSError) - MP_DEFINE_EXCEPTION(InterruptedError, OSError) - MP_DEFINE_EXCEPTION(IsADirectoryError, OSError) - MP_DEFINE_EXCEPTION(NotADirectoryError, OSError) - MP_DEFINE_EXCEPTION(PermissionError, OSError) - MP_DEFINE_EXCEPTION(ProcessLookupError, OSError) - MP_DEFINE_EXCEPTION(TimeoutError, OSError) - MP_DEFINE_EXCEPTION(FileExistsError, OSError) +#if MICROPY_PY_ASYNC_AWAIT + MP_DEFINE_EXCEPTION(StopAsyncIteration, Exception) +#endif + MP_DEFINE_EXCEPTION(StopIteration, Exception) + MP_DEFINE_EXCEPTION(ArithmeticError, Exception) + // MP_DEFINE_EXCEPTION(FloatingPointError, ArithmeticError) + MP_DEFINE_EXCEPTION(OverflowError, ArithmeticError) + MP_DEFINE_EXCEPTION(ZeroDivisionError, ArithmeticError) + MP_DEFINE_EXCEPTION(AssertionError, Exception) + MP_DEFINE_EXCEPTION(AttributeError, Exception) + // MP_DEFINE_EXCEPTION(BufferError, Exception) + // MP_DEFINE_EXCEPTION(EnvironmentError, Exception) use OSError instead + MP_DEFINE_EXCEPTION(EOFError, Exception) + MP_DEFINE_EXCEPTION(ImportError, Exception) + // MP_DEFINE_EXCEPTION(IOError, Exception) use OSError instead + MP_DEFINE_EXCEPTION(LookupError, Exception) + MP_DEFINE_EXCEPTION(IndexError, LookupError) + MP_DEFINE_EXCEPTION(KeyError, LookupError) + MP_DEFINE_EXCEPTION(MemoryError, Exception) + MP_DEFINE_EXCEPTION(NameError, Exception) + // MP_DEFINE_EXCEPTION(UnboundLocalError, NameError) + MP_DEFINE_EXCEPTION(OSError, Exception) + MP_DEFINE_EXCEPTION(ConnectionError, OSError) + MP_DEFINE_EXCEPTION(BrokenPipeError, ConnectionError) + // MP_DEFINE_EXCEPTION(ConnectionAbortedError, ConnectionError) + // MP_DEFINE_EXCEPTION(ConnectionRefusedError, ConnectionError) + // MP_DEFINE_EXCEPTION(ConnectionResetError, ConnectionError) + // MP_DEFINE_EXCEPTION(FileExistsError, OSError) MP_DEFINE_EXCEPTION(FileNotFoundError, OSError) - MP_DEFINE_EXCEPTION(ReferenceError, Exception) - */ -MP_DEFINE_EXCEPTION(RuntimeError, Exception) -MP_DEFINE_EXCEPTION(NotImplementedError, RuntimeError) -MP_DEFINE_EXCEPTION(SyntaxError, Exception) -MP_DEFINE_EXCEPTION(IndentationError, SyntaxError) -/* - MP_DEFINE_EXCEPTION(TabError, IndentationError) - */ -// MP_DEFINE_EXCEPTION(SystemError, Exception) -MP_DEFINE_EXCEPTION(TypeError, Exception) + // MP_DEFINE_EXCEPTION(InterruptedError, OSError) + // MP_DEFINE_EXCEPTION(IsADirectoryError, OSError) + // MP_DEFINE_EXCEPTION(NotADirectoryError, OSError) + // MP_DEFINE_EXCEPTION(PermissionError, OSError) + // MP_DEFINE_EXCEPTION(ProcessLookupError, OSError) + // MP_DEFINE_EXCEPTION(ReferenceError, Exception) + MP_DEFINE_EXCEPTION(TimeoutError, OSError) + MP_DEFINE_EXCEPTION(RuntimeError, Exception) + MP_DEFINE_EXCEPTION(NotImplementedError, RuntimeError) + MP_DEFINE_EXCEPTION(SyntaxError, Exception) + MP_DEFINE_EXCEPTION(IndentationError, SyntaxError) + // MP_DEFINE_EXCEPTION(TabError, IndentationError) + // MP_DEFINE_EXCEPTION(SystemError, Exception) + MP_DEFINE_EXCEPTION(TypeError, Exception) #if MICROPY_EMIT_NATIVE -MP_DEFINE_EXCEPTION(ViperTypeError, TypeError) + MP_DEFINE_EXCEPTION(ViperTypeError, TypeError) #endif -MP_DEFINE_EXCEPTION(ValueError, Exception) + MP_DEFINE_EXCEPTION(ValueError, Exception) #if MICROPY_PY_BUILTINS_STR_UNICODE -MP_DEFINE_EXCEPTION(UnicodeError, ValueError) -// TODO: Implement more UnicodeError subclasses which take arguments + MP_DEFINE_EXCEPTION(UnicodeError, ValueError) + //TODO: Implement more UnicodeError subclasses which take arguments #endif #if CIRCUITPY_ALARM MP_DEFINE_EXCEPTION(DeepSleepRequest, BaseException) @@ -413,7 +402,7 @@ mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type) { mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args) { assert(exc_type->make_new == mp_obj_exception_make_new); - return exc_type->make_new(exc_type, n_args, 0, args); + return mp_obj_exception_make_new(exc_type, n_args, 0, args); } #if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_NONE @@ -600,6 +589,16 @@ void mp_obj_exception_clear_traceback(mp_obj_t self_in) { void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block) { mp_obj_exception_t *self = mp_obj_exception_get_native(self_in); + #if MICROPY_PY_SYS_TRACEBACKLIMIT + mp_int_t max_traceback = MP_OBJ_SMALL_INT_VALUE(MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_TRACEBACKLIMIT])); + if (max_traceback <= 0) { + return; + } else if (self->traceback != NULL && self->traceback->len >= max_traceback * TRACEBACK_ENTRY_LEN) { + self->traceback->len -= TRACEBACK_ENTRY_LEN; + memmove(self->traceback->data, self->traceback->data + TRACEBACK_ENTRY_LEN, self->traceback->len * sizeof(self->traceback->data[0])); + } + #endif + // Try to allocate memory for the traceback, with fallback to emergency traceback object if (self->traceback == NULL || self->traceback == (mp_obj_traceback_t *)&mp_const_empty_traceback_obj) { self->traceback = m_new_obj_maybe(mp_obj_traceback_t); diff --git a/py/objexcept.h b/py/objexcept.h index 1230fdf18a536..80c06e90e061a 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * Copyright (c) 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objfilter.c b/py/objfilter.c index c034df28e62de..5292cfc550d73 100644 --- a/py/objfilter.c +++ b/py/objfilter.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -36,8 +36,7 @@ typedef struct _mp_obj_filter_t { STATIC mp_obj_t filter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, 2, false); - mp_obj_filter_t *o = m_new_obj(mp_obj_filter_t); - o->base.type = type; + mp_obj_filter_t *o = mp_obj_malloc(mp_obj_filter_t, type); o->fun = args[0]; o->iter = mp_getiter(args[1], NULL); return MP_OBJ_FROM_PTR(o); diff --git a/py/objfloat.c b/py/objfloat.c index 7aebcfdeb26ca..5666f3f5c218d 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -59,6 +59,14 @@ typedef struct _mp_obj_float_t { const mp_obj_float_t mp_const_float_e_obj = {{&mp_type_float}, (mp_float_t)M_E}; const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, (mp_float_t)M_PI}; +#if MICROPY_PY_MATH_CONSTANTS +#ifndef NAN +#error NAN macro is not defined +#endif +const mp_obj_float_t mp_const_float_tau_obj = {{&mp_type_float}, (mp_float_t)(2.0 * M_PI)}; +const mp_obj_float_t mp_const_float_inf_obj = {{&mp_type_float}, (mp_float_t)INFINITY}; +const mp_obj_float_t mp_const_float_nan_obj = {{&mp_type_float}, (mp_float_t)NAN}; +#endif #endif @@ -194,7 +202,8 @@ const mp_obj_type_t mp_type_float = { #if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C && MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D mp_obj_t mp_obj_new_float(mp_float_t value) { - mp_obj_float_t *o = m_new(mp_obj_float_t, 1); + // Don't use mp_obj_malloc here to avoid extra function call overhead. + mp_obj_float_t *o = m_new_obj(mp_obj_float_t); o->base.type = &mp_type_float; o->value = value; return MP_OBJ_FROM_PTR(o); diff --git a/py/objfun.c b/py/objfun.c index 5a02869fcf21b..eb4a2bfe2518d 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -155,19 +155,23 @@ const mp_obj_type_t mp_type_fun_builtin_var = { /******************************************************************************/ /* byte code functions */ -qstr mp_obj_code_get_name(const byte *code_info) { +STATIC qstr mp_obj_code_get_name(const mp_obj_fun_bc_t *fun, const byte *code_info) { MP_BC_PRELUDE_SIZE_DECODE(code_info); - #if MICROPY_PERSISTENT_CODE - return code_info[0] | (code_info[1] << 8); - #else - return mp_decode_uint_value(code_info); + mp_uint_t name = mp_decode_uint_value(code_info); + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + name = fun->context->constants.qstr_table[name]; #endif + return name; } +#if MICROPY_EMIT_NATIVE +STATIC const mp_obj_type_t mp_type_fun_native; +#endif + qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) { const mp_obj_fun_bc_t *fun = MP_OBJ_TO_PTR(fun_in); #if MICROPY_EMIT_NATIVE - if (fun->base.type == &mp_type_fun_native) { + if (fun->base.type == &mp_type_fun_native || fun->base.type == &mp_type_native_gen_wrap) { // TODO native functions don't have name stored return MP_QSTR_; } @@ -175,14 +179,14 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) { const byte *bc = fun->bytecode; MP_BC_PRELUDE_SIG_DECODE(bc); - return mp_obj_code_get_name(bc); + return mp_obj_code_get_name(fun, bc); } #if MICROPY_CPYTHON_COMPAT STATIC void fun_bc_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_fun_bc_t *o = MP_OBJ_TO_PTR(o_in); - mp_printf(print, "", mp_obj_fun_get_name(o_in), o); + mp_printf(print, "", mp_obj_fun_get_name(o_in), o); } #endif @@ -217,7 +221,6 @@ STATIC void dump_args(const mp_obj_t *a, size_t sz) { #define INIT_CODESTATE(code_state, _fun_bc, _n_state, n_args, n_kw, args) \ code_state->fun_bc = _fun_bc; \ - code_state->ip = 0; \ code_state->n_state = _n_state; \ mp_setup_code_state(code_state, n_args, n_kw, args); \ code_state->old_globals = mp_globals_get(); @@ -248,7 +251,7 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args INIT_CODESTATE(code_state, self, n_state, n_args, n_kw, args); // execute the byte code with the correct globals context - mp_globals_set(self->globals); + mp_globals_set(self->context->module.globals); return code_state; } @@ -293,7 +296,7 @@ STATIC mp_obj_t PLACE_IN_ITCM(fun_bc_call)(mp_obj_t self_in, size_t n_args, size INIT_CODESTATE(code_state, self, n_state, n_args, n_kw, args); // execute the byte code with the correct globals context - mp_globals_set(self->globals); + mp_globals_set(self->context->module.globals); mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode(code_state, MP_OBJ_NULL); mp_globals_set(code_state->old_globals); @@ -366,7 +369,7 @@ void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } if (attr == MP_QSTR___globals__) { mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); - dest[0] = MP_OBJ_FROM_PTR(self->globals); + dest[0] = MP_OBJ_FROM_PTR(self->context->module.globals); } } #endif @@ -387,25 +390,28 @@ const mp_obj_type_t mp_type_fun_bc = { ), }; -mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byte *code, const mp_uint_t *const_table) { +mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_module_context_t *context, struct _mp_raw_code_t *const *child_table) { size_t n_def_args = 0; size_t n_extra_args = 0; - mp_obj_tuple_t *def_args = MP_OBJ_TO_PTR(def_args_in); - if (def_args_in != MP_OBJ_NULL) { - assert(mp_obj_is_type(def_args_in, &mp_type_tuple)); - n_def_args = def_args->len; - n_extra_args = def_args->len; + mp_obj_tuple_t *def_pos_args = NULL; + mp_obj_t def_kw_args = MP_OBJ_NULL; + if (def_args != NULL && def_args[0] != MP_OBJ_NULL) { + assert(mp_obj_is_type(def_args[0], &mp_type_tuple)); + def_pos_args = MP_OBJ_TO_PTR(def_args[0]); + n_def_args = def_pos_args->len; + n_extra_args = def_pos_args->len; } - if (def_kw_args != MP_OBJ_NULL) { + if (def_args != NULL && def_args[1] != MP_OBJ_NULL) { + assert(mp_obj_is_type(def_args[1], &mp_type_dict)); + def_kw_args = def_args[1]; n_extra_args += 1; } - mp_obj_fun_bc_t *o = m_new_obj_var(mp_obj_fun_bc_t, mp_obj_t, n_extra_args); - o->base.type = &mp_type_fun_bc; - o->globals = mp_globals_get(); + mp_obj_fun_bc_t *o = mp_obj_malloc_var(mp_obj_fun_bc_t, mp_obj_t, n_extra_args, &mp_type_fun_bc); o->bytecode = code; - o->const_table = const_table; - if (def_args != NULL) { - memcpy(o->extra_args, def_args->items, n_def_args * sizeof(mp_obj_t)); + o->context = context; + o->child_table = child_table; + if (def_pos_args != NULL) { + memcpy(o->extra_args, def_pos_args->items, n_def_args * sizeof(mp_obj_t)); } if (def_kw_args != MP_OBJ_NULL) { o->extra_args[n_def_args] = def_kw_args; @@ -420,12 +426,12 @@ mp_obj_t mp_obj_new_fun_bc(mp_obj_t def_args_in, mp_obj_t def_kw_args, const byt STATIC mp_obj_t PLACE_IN_ITCM(fun_native_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { MP_STACK_CHECK(); - mp_obj_fun_bc_t *self = self_in; + mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); mp_call_fun_t fun = MICROPY_MAKE_POINTER_CALLABLE((void *)self->bytecode); return fun(self_in, n_args, n_kw, args); } -const mp_obj_type_t mp_type_fun_native = { +STATIC const mp_obj_type_t mp_type_fun_native = { { &mp_type_type }, .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_EXTENDED, .name = MP_QSTR_function, @@ -435,10 +441,10 @@ const mp_obj_type_t mp_type_fun_native = { ), }; -mp_obj_t mp_obj_new_fun_native(mp_obj_t def_args_in, mp_obj_t def_kw_args, const void *fun_data, const mp_uint_t *const_table) { - mp_obj_fun_bc_t *o = mp_obj_new_fun_bc(def_args_in, def_kw_args, (const byte *)fun_data, const_table); +mp_obj_t mp_obj_new_fun_native(const mp_obj_t *def_args, const void *fun_data, const mp_module_context_t *mc, struct _mp_raw_code_t *const *child_table) { + mp_obj_fun_bc_t *o = MP_OBJ_TO_PTR(mp_obj_new_fun_bc(def_args, (const byte *)fun_data, mc, child_table)); o->base.type = &mp_type_fun_native; - return o; + return MP_OBJ_FROM_PTR(o); } #endif // MICROPY_EMIT_NATIVE @@ -546,12 +552,11 @@ STATIC const mp_obj_type_t mp_type_fun_asm = { }; mp_obj_t mp_obj_new_fun_asm(size_t n_args, const void *fun_data, mp_uint_t type_sig) { - mp_obj_fun_asm_t *o = m_new_obj(mp_obj_fun_asm_t); - o->base.type = &mp_type_fun_asm; + mp_obj_fun_asm_t *o = mp_obj_malloc(mp_obj_fun_asm_t, &mp_type_fun_asm); o->n_args = n_args; o->fun_data = fun_data; o->type_sig = type_sig; - return o; + return MP_OBJ_FROM_PTR(o); } #endif // MICROPY_EMIT_INLINE_ASM diff --git a/py/objfun.h b/py/objfun.h index aae780b310f29..9de15b8841553 100644 --- a/py/objfun.h +++ b/py/objfun.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,13 +26,14 @@ #ifndef MICROPY_INCLUDED_PY_OBJFUN_H #define MICROPY_INCLUDED_PY_OBJFUN_H +#include "py/bc.h" #include "py/obj.h" typedef struct _mp_obj_fun_bc_t { mp_obj_base_t base; - mp_obj_dict_t *globals; // the context within which this function was defined - const byte *bytecode; // bytecode for the function - const mp_uint_t *const_table; // constant table + const mp_module_context_t *context; // context within which this function was defined + struct _mp_raw_code_t *const *child_table; // table of children + const byte *bytecode; // bytecode for the function #if MICROPY_PY_SYS_SETTRACE const struct _mp_raw_code_t *rc; #endif @@ -42,6 +43,9 @@ typedef struct _mp_obj_fun_bc_t { mp_obj_t extra_args[]; } mp_obj_fun_bc_t; +mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_module_context_t *cm, struct _mp_raw_code_t *const *raw_code_table); +mp_obj_t mp_obj_new_fun_native(const mp_obj_t *def_args, const void *fun_data, const mp_module_context_t *cm, struct _mp_raw_code_t *const *raw_code_table); +mp_obj_t mp_obj_new_fun_asm(size_t n_args, const void *fun_data, mp_uint_t type_sig); void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); #endif // MICROPY_INCLUDED_PY_OBJFUN_H diff --git a/py/objgenerator.c b/py/objgenerator.c index 7c3ec99307bc0..4443f81ce1b24 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky + * Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,7 @@ #include "supervisor/shared/translate/translate.h" // Instance of GeneratorExit exception - needed by generator.close() +// CIRCUITPY: https://github.com/adafruit/circuitpython/pull/7069 fix #if MICROPY_CONST_GENERATOREXIT_OBJ const mp_obj_exception_t mp_static_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj}; @@ -49,59 +50,117 @@ mp_obj_exception_t mp_static_GeneratorExit_obj; /******************************************************************************/ /* generator wrapper */ -typedef struct _mp_obj_gen_wrap_t { - mp_obj_base_t base; - mp_obj_t *fun; - bool coroutine_generator; -} mp_obj_gen_wrap_t; - typedef struct _mp_obj_gen_instance_t { mp_obj_base_t base; // mp_const_none: Not-running, no exception. // MP_OBJ_NULL: Running, no exception. // other: Not running, pending exception. mp_obj_t pend_exc; - bool coroutine_generator; mp_code_state_t code_state; } mp_obj_gen_instance_t; +STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + // A generating or coroutine function is just a bytecode function + // with type mp_type_gen_wrap or mp_type_coro_wrap. + mp_obj_fun_bc_t *self_fun = MP_OBJ_TO_PTR(self_in); + + // bytecode prelude: get state size and exception stack size + const uint8_t *ip = self_fun->bytecode; + MP_BC_PRELUDE_SIG_DECODE(ip); + + // allocate the generator or coroutine object, with room for local stack and exception stack + mp_obj_gen_instance_t *o = mp_obj_malloc_var(mp_obj_gen_instance_t, byte, + n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t), + #if MICROPY_PY_ASYNC_AWAIT + self_fun->base.type == &mp_type_gen_wrap ? &mp_type_gen_instance : &mp_type_coro_instance + #else + &mp_type_gen_instance + #endif + ); + + o->pend_exc = mp_const_none; + o->code_state.fun_bc = self_fun; + o->code_state.n_state = n_state; + mp_setup_code_state(&o->code_state, n_args, n_kw, args); + return MP_OBJ_FROM_PTR(o); +} + +const mp_obj_type_t mp_type_gen_wrap = { + { &mp_type_type }, + .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_generator, + #if MICROPY_PY_FUNCTION_ATTRS + .attr = mp_obj_fun_bc_attr, + #endif + MP_TYPE_EXTENDED_FIELDS( + .call = gen_wrap_call, + .unary_op = mp_generic_unary_op, + ), +}; + +#if MICROPY_PY_ASYNC_AWAIT +const mp_obj_type_t mp_type_coro_wrap = { + { &mp_type_type }, + .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_coroutine, + #if MICROPY_PY_FUNCTION_ATTRS + .attr = mp_obj_fun_bc_attr, + #endif + MP_TYPE_EXTENDED_FIELDS( + .call = gen_wrap_call, + .unary_op = mp_generic_unary_op, + ), +}; +#endif + /******************************************************************************/ // native generator wrapper #if MICROPY_EMIT_NATIVE +// Based on mp_obj_gen_instance_t. +typedef struct _mp_obj_gen_instance_native_t { + mp_obj_base_t base; + mp_obj_t pend_exc; + mp_code_state_native_t code_state; +} mp_obj_gen_instance_native_t; + STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_obj_gen_wrap_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t *)self->fun; + // The state for a native generating function is held in the same struct as a bytecode function + mp_obj_fun_bc_t *self_fun = MP_OBJ_TO_PTR(self_in); - // Determine start of prelude, and extract n_state from it + // Determine start of prelude. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - uintptr_t prelude_offset = ((uintptr_t *)self_fun->bytecode)[0]; + uintptr_t prelude_ptr_index = ((uintptr_t *)self_fun->bytecode)[0]; #pragma GCC diagnostic pop + const uint8_t *prelude_ptr; + if (prelude_ptr_index == 0) { + prelude_ptr = (void *)self_fun->child_table; + } else { + prelude_ptr = (void *)self_fun->child_table[prelude_ptr_index]; + } - #if MICROPY_EMIT_NATIVE_PRELUDE_AS_BYTES_OBJ - // Prelude is in bytes object in const_table, at index prelude_offset - mp_obj_str_t *prelude_bytes = MP_OBJ_TO_PTR(self_fun->const_table[prelude_offset]); - prelude_offset = (const byte *)prelude_bytes->data - self_fun->bytecode; - #endif - const uint8_t *ip = self_fun->bytecode + prelude_offset; - size_t n_state, n_exc_stack_unused, scope_flags, n_pos_args, n_kwonly_args, n_def_args; - MP_BC_PRELUDE_SIG_DECODE_INTO(ip, n_state, n_exc_stack_unused, scope_flags, n_pos_args, n_kwonly_args, n_def_args); - size_t n_exc_stack = 0; + // Extract n_state from the prelude. + const uint8_t *ip = prelude_ptr; + MP_BC_PRELUDE_SIG_DECODE(ip); - // Allocate the generator object, with room for local stack and exception stack - mp_obj_gen_instance_t *o = m_new_obj_var(mp_obj_gen_instance_t, byte, - n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t)); - o->base.type = &mp_type_gen_instance; + // Allocate the generator object, with room for local stack (exception stack not needed). + mp_obj_gen_instance_native_t *o = mp_obj_malloc_var(mp_obj_gen_instance_native_t, byte, n_state * sizeof(mp_obj_t), + #if MICROPY_PY_ASYNC_AWAIT + (self_fun->base.type == &mp_type_native_gen_wrap) ? &mp_type_gen_instance : &mp_type_coro_instance + #else + &mp_type_gen_instance + #endif + ); // 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; + o->code_state.ip = prelude_ptr; o->code_state.n_state = n_state; - mp_setup_code_state(&o->code_state, n_args, n_kw, args); + o->code_state.sp = &o->code_state.state[0] - 1; + mp_setup_code_state_native(&o->code_state, n_args, n_kw, args); // Indicate we are a native function, which doesn't use this variable o->code_state.exc_sp_idx = MP_CODE_STATE_EXC_SP_IDX_SENTINEL; @@ -116,71 +175,35 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k return MP_OBJ_FROM_PTR(o); } -#endif // MICROPY_EMIT_NATIVE - -STATIC mp_obj_t bc_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_obj_gen_wrap_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t *)self->fun; - assert(self_fun->base.type == &mp_type_fun_bc); - - // bytecode prelude: get state size and exception stack size - const uint8_t *ip = self_fun->bytecode; - MP_BC_PRELUDE_SIG_DECODE(ip); - - // allocate the generator object, with room for local stack and exception stack - mp_obj_gen_instance_t *o = m_new_obj_var(mp_obj_gen_instance_t, byte, - n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t)); - o->base.type = &mp_type_gen_instance; - - o->coroutine_generator = self->coroutine_generator; - o->pend_exc = mp_const_none; - o->code_state.fun_bc = self_fun; - o->code_state.ip = 0; - o->code_state.n_state = n_state; - mp_setup_code_state(&o->code_state, n_args, n_kw, args); - return MP_OBJ_FROM_PTR(o); -} - -STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - #if MICROPY_EMIT_NATIVE - mp_obj_gen_wrap_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t *)self->fun; - if (self_fun->base.type == &mp_type_fun_native) { - return native_gen_wrap_call(self, n_args, n_kw, args); - } - #endif - return bc_gen_wrap_call(self_in, n_args, n_kw, args); -} - -#if MICROPY_PY_FUNCTION_ATTRS -static void gen_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { - mp_obj_gen_wrap_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t *)self->fun; - mp_obj_fun_bc_attr(MP_OBJ_FROM_PTR(self_fun), attr, dest); -} -#endif - -const mp_obj_type_t mp_type_gen_wrap = { +const mp_obj_type_t mp_type_native_gen_wrap = { { &mp_type_type }, .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_EXTENDED, .name = MP_QSTR_generator, #if MICROPY_PY_FUNCTION_ATTRS - .attr = gen_attr, + .attr = mp_obj_fun_bc_attr, #endif MP_TYPE_EXTENDED_FIELDS( - .call = gen_wrap_call, + .call = native_gen_wrap_call, .unary_op = mp_generic_unary_op, ), }; +#if MICROPY_PY_ASYNC_AWAIT +const mp_obj_type_t mp_type_native_coro_wrap = { + { &mp_type_type }, + .flags = MP_TYPE_FLAG_BINDS_SELF | MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_coroutine, + #if MICROPY_PY_FUNCTION_ATTRS + .attr = mp_obj_fun_bc_attr, + #endif + MP_TYPE_EXTENDED_FIELDS( + .call = native_gen_wrap_call, + .unary_op = mp_generic_unary_op, + ), +}; +#endif -mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun, bool is_coroutine) { - mp_obj_gen_wrap_t *o = m_new_obj(mp_obj_gen_wrap_t); - o->base.type = &mp_type_gen_wrap; - o->fun = MP_OBJ_TO_PTR(fun); - o->coroutine_generator = is_coroutine; - return MP_OBJ_FROM_PTR(o); -} +#endif // MICROPY_EMIT_NATIVE /******************************************************************************/ /* generator instance */ @@ -188,20 +211,29 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun, bool is_coroutine) { STATIC void gen_instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); - #if MICROPY_PY_ASYNC_AWAIT - if (self->coroutine_generator) { - mp_printf(print, "<%q object '%q' at %p>", MP_QSTR_coroutine, mp_obj_fun_get_name(MP_OBJ_FROM_PTR(self->code_state.fun_bc)), self); - } else { - mp_printf(print, "<%q object '%q' at %p>", MP_QSTR_generator, mp_obj_fun_get_name(MP_OBJ_FROM_PTR(self->code_state.fun_bc)), self); - } - #else mp_printf(print, "", mp_obj_fun_get_name(MP_OBJ_FROM_PTR(self->code_state.fun_bc)), self); - #endif } +// CIRCUITPY +#if MICROPY_PY_ASYNC_AWAIT +STATIC void coro_instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + (void)kind; + mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); + mp_printf(print, "", mp_obj_fun_get_name(MP_OBJ_FROM_PTR(self->code_state.fun_bc)), self); +} +#endif + mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) { MP_STACK_CHECK(); - mp_check_self(mp_obj_is_type(self_in, &mp_type_gen_instance)); + // CIRCUITPY + // note that self may have as its type either gen or coro, + // both of which are stored as an mp_obj_gen_instance_t . + mp_check_self( + mp_obj_is_type(self_in, &mp_type_gen_instance) + #if MICROPY_PY_ASYNC_AWAIT + || mp_obj_is_type(self_in, &mp_type_coro_instance) + #endif + ); mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); if (self->code_state.ip == 0) { // Trying to resume an already stopped generator. @@ -209,7 +241,6 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ *ret_val = mp_const_none; return MP_VM_RETURN_NORMAL; } - // Ensure the generator cannot be reentered during execution if (self->pend_exc == MP_OBJ_NULL) { mp_raise_ValueError(MP_ERROR_TEXT("generator already executing")); @@ -223,7 +254,13 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ #endif // If the generator is started, allow sending a value. - if (self->code_state.sp == self->code_state.state - 1) { + void *state_start = self->code_state.state - 1; + #if MICROPY_EMIT_NATIVE + if (self->code_state.exc_sp_idx == MP_CODE_STATE_EXC_SP_IDX_SENTINEL) { + state_start = ((mp_obj_gen_instance_native_t *)self)->code_state.state - 1; + } + #endif + if (self->code_state.sp == state_start) { if (send_value != mp_const_none) { mp_raise_TypeError(MP_ERROR_TEXT("can't send non-None value to a just-started generator")); } @@ -236,7 +273,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ // Set up the correct globals context for the generator and execute it self->code_state.old_globals = mp_globals_get(); - mp_globals_set(self->code_state.fun_bc->globals); + mp_globals_set(self->code_state.fun_bc->context->module.globals); mp_vm_return_kind_t ret_kind; @@ -278,7 +315,14 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ case MP_VM_RETURN_EXCEPTION: { self->code_state.ip = 0; - *ret_val = self->code_state.state[0]; + #if MICROPY_EMIT_NATIVE + if (self->code_state.exc_sp_idx == MP_CODE_STATE_EXC_SP_IDX_SENTINEL) { + *ret_val = ((mp_obj_gen_instance_native_t *)self)->code_state.state[0]; + } else + #endif + { + *ret_val = self->code_state.state[0]; + } // PEP479: if StopIteration is raised inside a generator it is replaced with RuntimeError if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(*ret_val)), MP_OBJ_FROM_PTR(&mp_type_StopIteration))) { *ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("generator raised StopIteration")); @@ -293,6 +337,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, bool raise_stop_iteration) { mp_obj_t ret; switch (mp_obj_gen_resume(self_in, send_value, throw_value, &ret)) { + case MP_VM_RETURN_NORMAL: default: // A normal return is a StopIteration, either raise it or return @@ -315,13 +360,6 @@ STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_o } STATIC mp_obj_t gen_instance_iternext(mp_obj_t self_in) { - #if MICROPY_PY_ASYNC_AWAIT - // This translate is literally too much for m0 boards - mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); - if (self->coroutine_generator) { - mp_raise_TypeError(MP_ERROR_TEXT("'coroutine' object is not an iterator")); - } - #endif return gen_resume_and_raise(self_in, mp_const_none, MP_OBJ_NULL, false); } @@ -331,21 +369,12 @@ STATIC mp_obj_t gen_instance_send(mp_obj_t self_in, mp_obj_t send_value) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(gen_instance_send_obj, gen_instance_send); #if MICROPY_PY_ASYNC_AWAIT -STATIC mp_obj_t gen_instance_await(mp_obj_t self_in) { - mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in); - if (!self->coroutine_generator) { - // Pretend like a generator does not have this coroutine behavior. - // Pay no attention to the dir() behind the curtain - mp_raise_msg_varg(&mp_type_AttributeError, MP_ERROR_TEXT("type object '%q' has no attribute '%q'"), - MP_QSTR_generator, MP_QSTR___await__); - } - // You can directly call send on a coroutine generator or you can __await__ then send on the return of that. - return self; +STATIC mp_obj_t coro_instance_await(mp_obj_t self_in) { + return self_in; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(gen_instance_await_obj, gen_instance_await); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(coro_instance_await_obj, coro_instance_await); #endif -STATIC mp_obj_t gen_instance_close(mp_obj_t self_in); STATIC mp_obj_t gen_instance_throw(size_t n_args, const mp_obj_t *args) { // The signature of this function is: throw(type[, value[, traceback]]) // CPython will pass all given arguments through the call chain and process them @@ -417,9 +446,6 @@ STATIC const mp_rom_map_elem_t gen_instance_locals_dict_table[] = { #if MICROPY_PY_GENERATOR_PEND_THROW { MP_ROM_QSTR(MP_QSTR_pend_throw), MP_ROM_PTR(&gen_instance_pend_throw_obj) }, #endif - #if MICROPY_PY_ASYNC_AWAIT - { MP_ROM_QSTR(MP_QSTR___await__), MP_ROM_PTR(&gen_instance_await_obj) }, - #endif }; STATIC MP_DEFINE_CONST_DICT(gen_instance_locals_dict, gen_instance_locals_dict_table); @@ -436,3 +462,35 @@ const mp_obj_type_t mp_type_gen_instance = { .iternext = gen_instance_iternext, ), }; + +#if MICROPY_PY_ASYNC_AWAIT +// CIRCUITPY +// coroutine instance locals dict and type +// same as generator, but with addition of __await()__. +STATIC const mp_rom_map_elem_t coro_instance_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&gen_instance_close_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&gen_instance_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_throw), MP_ROM_PTR(&gen_instance_throw_obj) }, + #if MICROPY_PY_GENERATOR_PEND_THROW + { MP_ROM_QSTR(MP_QSTR_pend_throw), MP_ROM_PTR(&gen_instance_pend_throw_obj) }, + #endif + #if MICROPY_PY_ASYNC_AWAIT + { MP_ROM_QSTR(MP_QSTR___await__), MP_ROM_PTR(&coro_instance_await_obj) }, + #endif +}; + +STATIC MP_DEFINE_CONST_DICT(coro_instance_locals_dict, coro_instance_locals_dict_table); + +const mp_obj_type_t mp_type_coro_instance = { + { &mp_type_type }, + .flags = MP_TYPE_FLAG_EXTENDED, + .name = MP_QSTR_coroutine, + .print = coro_instance_print, + .locals_dict = (mp_obj_dict_t *)&coro_instance_locals_dict, + MP_TYPE_EXTENDED_FIELDS( + .unary_op = mp_generic_unary_op, + .getiter = mp_identity_getiter, + .iternext = gen_instance_iternext, + ), +}; +#endif diff --git a/py/objgenerator.h b/py/objgenerator.h index 4b7f8c1ac51a5..80bf9cd8603f0 100644 --- a/py/objgenerator.h +++ b/py/objgenerator.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objgetitemiter.c b/py/objgetitemiter.c index 098e7da557b64..d841212649407 100644 --- a/py/objgetitemiter.c +++ b/py/objgetitemiter.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objint.c b/py/objint.c index 6dc675823f996..83987d690a151 100644 --- a/py/objint.c +++ b/py/objint.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -396,7 +396,7 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i // This is called only with strings whose value doesn't fit in SMALL_INT mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { - mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("small int overflow")); + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("No long integer support")); return mp_const_none; } diff --git a/py/objint.h b/py/objint.h index fb491914f283e..83f12bac6cde1 100644 --- a/py/objint.h +++ b/py/objint.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objint_longlong.c b/py/objint_longlong.c index d318eab38e5cc..ba23825abf408 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -256,8 +256,7 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) { } mp_obj_t mp_obj_new_int_from_ll(long long val) { - mp_obj_int_t *o = m_new_obj(mp_obj_int_t); - o->base.type = &mp_type_int; + mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); o->val = val; return o; } @@ -267,8 +266,7 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { if (val >> (sizeof(unsigned long long) * 8 - 1) != 0) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ulonglong too large")); } - mp_obj_int_t *o = m_new_obj(mp_obj_int_t); - o->base.type = &mp_type_int; + mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); o->val = val; return o; } @@ -276,8 +274,7 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { // TODO this does not honor the given length of the string, but it all cases it should anyway be null terminated // TODO check overflow - mp_obj_int_t *o = m_new_obj(mp_obj_int_t); - o->base.type = &mp_type_int; + mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); char *endptr; o->val = strtoll(*str, &endptr, base); *str = endptr; diff --git a/py/objint_mpz.c b/py/objint_mpz.c index e147e5f08ad22..603a5b986c13d 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -77,8 +77,7 @@ const mp_obj_int_t mp_sys_maxsize_obj = { #endif mp_obj_int_t *mp_obj_int_new_mpz(void) { - mp_obj_int_t *o = m_new_obj(mp_obj_int_t); - o->base.type = &mp_type_int; + mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); mpz_init_zero(&o->mpz); return o; } diff --git a/py/objlist.c b/py/objlist.c index 434bca7d0a13c..f95c322bd5489 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objlist.h b/py/objlist.h index eb005e81cf60b..79ed6c288ca66 100644 --- a/py/objlist.h +++ b/py/objlist.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objmap.c b/py/objmap.c index dc1dc1387da9d..d87105c089a78 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,7 @@ typedef struct _mp_obj_map_t { STATIC mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, MP_OBJ_FUN_ARGS_MAX, false); - mp_obj_map_t *o = m_new_obj_var(mp_obj_map_t, mp_obj_t, n_args - 1); - o->base.type = type; + mp_obj_map_t *o = mp_obj_malloc_var(mp_obj_map_t, mp_obj_t, n_args - 1, type); o->n_iters = n_args - 1; o->fun = args[0]; for (size_t i = 0; i < n_args - 1; i++) { diff --git a/py/objmodule.c b/py/objmodule.c index 8f04a445977b5..1c281793d67c3 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2015 Paul Sokolovsky + * Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2014-2015 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,12 +29,16 @@ #include #include -#include "py/gc.h" +#include "py/bc.h" #include "py/objmodule.h" #include "py/runtime.h" #include "py/builtin.h" +#ifndef NO_QSTR +// Only include module definitions when not doing qstr extraction, because the +// qstr extraction stage also generates this module definition header file. #include "genhdr/moduledefs.h" +#endif #if MICROPY_MODULE_BUILTIN_INIT STATIC void mp_module_call_init(mp_obj_t module_name, mp_obj_t module_obj); @@ -63,6 +67,21 @@ STATIC void module_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kin mp_printf(print, "", module_name); } +STATIC void module_attr_try_delegation(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + #if MICROPY_MODULE_ATTR_DELEGATION + // Delegate lookup to a module's custom attr method (found in last lot of globals dict). + mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); + mp_map_t *map = &self->globals->map; + if (map->table[map->alloc - 1].key == MP_OBJ_NEW_QSTR(MP_QSTRnull)) { + ((mp_attr_fun_t)MP_OBJ_TO_PTR(map->table[map->alloc - 1].value))(self_in, attr, dest); + } + #else + (void)self_in; + (void)attr; + (void)dest; + #endif +} + STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); if (dest[0] == MP_OBJ_NULL) { @@ -75,29 +94,28 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(MP_QSTR___getattr__), MP_MAP_LOOKUP); if (elem != NULL) { dest[0] = mp_call_function_1(elem->value, MP_OBJ_NEW_QSTR(attr)); + } else { + module_attr_try_delegation(self_in, attr, dest); } #endif + } else { + module_attr_try_delegation(self_in, attr, dest); } } else { // delete/store attribute mp_obj_dict_t *dict = self->globals; if (dict->map.is_fixed) { - mp_map_elem_t *elem = mp_map_lookup(&dict->map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); #if MICROPY_CAN_OVERRIDE_BUILTINS if (dict == &mp_module_builtins_globals) { if (MP_STATE_VM(mp_module_builtins_override_dict) == NULL) { - MP_STATE_VM(mp_module_builtins_override_dict) = gc_make_long_lived(MP_OBJ_TO_PTR(mp_obj_new_dict(1))); + MP_STATE_VM(mp_module_builtins_override_dict) = MP_OBJ_TO_PTR(mp_obj_new_dict(1)); } dict = MP_STATE_VM(mp_module_builtins_override_dict); } else #endif - // Return success if the given value is already in the dictionary. This is the case for - // native packages with native submodules. - if (elem != NULL && elem->value == dest[1]) { - dest[0] = MP_OBJ_NULL; // indicate success - return; - } else { + { // can't delete or store to fixed map + module_attr_try_delegation(self_in, attr, dest); return; } } @@ -106,9 +124,7 @@ STATIC void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_dict_delete(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr)); } else { // store attribute - mp_obj_t long_lived = MP_OBJ_FROM_PTR(gc_make_long_lived(MP_OBJ_TO_PTR(dest[1]))); - // TODO CPython allows STORE_ATTR to a module, but is this the correct implementation? - mp_obj_dict_store(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr), long_lived); + mp_obj_dict_store(MP_OBJ_FROM_PTR(dict), MP_OBJ_NEW_QSTR(attr), dest[1]); } dest[0] = MP_OBJ_NULL; // indicate success } @@ -131,12 +147,12 @@ mp_obj_t mp_obj_new_module(qstr module_name) { } // create new module object - mp_obj_module_t *o = m_new_ll_obj(mp_obj_module_t); - o->base.type = &mp_type_module; - o->globals = gc_make_long_lived(MP_OBJ_TO_PTR(mp_obj_new_dict(MICROPY_MODULE_DICT_SIZE))); + mp_module_context_t *o = m_new_obj(mp_module_context_t); + o->module.base.type = &mp_type_module; + o->module.globals = MP_OBJ_TO_PTR(mp_obj_new_dict(MICROPY_MODULE_DICT_SIZE)); // store __name__ entry in the module - mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(module_name)); + mp_obj_dict_store(MP_OBJ_FROM_PTR(o->module.globals), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(module_name)); // store the new module into the slot in the global dict holding all modules el->value = MP_OBJ_FROM_PTR(o); @@ -161,102 +177,8 @@ void mp_obj_module_set_globals(mp_obj_t self_in, mp_obj_dict_t *globals) { // Global module table and related functions STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = { - { MP_ROM_QSTR(MP_QSTR___main__), MP_ROM_PTR(&mp_module___main__) }, - { MP_ROM_QSTR(MP_QSTR_builtins), MP_ROM_PTR(&mp_module_builtins) }, - { MP_ROM_QSTR(MP_QSTR_micropython), MP_ROM_PTR(&mp_module_micropython) }, - - #if MICROPY_PY_IO - #if CIRCUITPY - { MP_ROM_QSTR(MP_QSTR_io), MP_ROM_PTR(&mp_module_io) }, - #else - { MP_ROM_QSTR(MP_QSTR_uio), MP_ROM_PTR(&mp_module_io) }, - #endif - #endif - #if MICROPY_PY_COLLECTIONS - { MP_ROM_QSTR(MP_QSTR_collections), MP_ROM_PTR(&mp_module_collections) }, - #endif -// CircuitPython: Now in shared-bindings/, so not defined here. - #if MICROPY_PY_STRUCT - { MP_ROM_QSTR(MP_QSTR_ustruct), MP_ROM_PTR(&mp_module_ustruct) }, - #endif - - #if MICROPY_PY_BUILTINS_FLOAT - #if MICROPY_PY_MATH - { MP_ROM_QSTR(MP_QSTR_math), MP_ROM_PTR(&mp_module_math) }, - #endif - #if MICROPY_PY_BUILTINS_COMPLEX && MICROPY_PY_CMATH - { MP_ROM_QSTR(MP_QSTR_cmath), MP_ROM_PTR(&mp_module_cmath) }, - #endif - #endif - #if MICROPY_PY_SYS - { MP_ROM_QSTR(MP_QSTR_sys), MP_ROM_PTR(&mp_module_sys) }, - #endif - #if MICROPY_PY_GC && MICROPY_ENABLE_GC - { MP_ROM_QSTR(MP_QSTR_gc), MP_ROM_PTR(&mp_module_gc) }, - #endif - #if MICROPY_PY_THREAD - { MP_ROM_QSTR(MP_QSTR__thread), MP_ROM_PTR(&mp_module_thread) }, - #endif - - // extmod modules - - // Modules included in CircuitPython are registered using MP_REGISTER_MODULE, - // and do not have the "u" prefix. - - #if MICROPY_PY_UASYNCIO && !CIRCUITPY - { MP_ROM_QSTR(MP_QSTR__uasyncio), MP_ROM_PTR(&mp_module_uasyncio) }, - #endif - #if MICROPY_PY_UERRNO && !CIRCUITPY - { MP_ROM_QSTR(MP_QSTR_uerrno), MP_ROM_PTR(&mp_module_uerrno) }, - #endif - #if MICROPY_PY_UCTYPES - { MP_ROM_QSTR(MP_QSTR_uctypes), MP_ROM_PTR(&mp_module_uctypes) }, - #endif - #if MICROPY_PY_UZLIB - { MP_ROM_QSTR(MP_QSTR_uzlib), MP_ROM_PTR(&mp_module_uzlib) }, - #endif - #if MICROPY_PY_UJSON && !CIRCUITPY - { MP_ROM_QSTR(MP_QSTR_ujson), MP_ROM_PTR(&mp_module_ujson) }, - #endif - #if MICROPY_PY_URE && !CIRCUITPY - { MP_ROM_QSTR(MP_QSTR_ure), MP_ROM_PTR(&mp_module_ure) }, - #endif - #if MICROPY_PY_UHEAPQ - { MP_ROM_QSTR(MP_QSTR_uheapq), MP_ROM_PTR(&mp_module_uheapq) }, - #endif - #if MICROPY_PY_UTIMEQ - { MP_ROM_QSTR(MP_QSTR_utimeq), MP_ROM_PTR(&mp_module_utimeq) }, - #endif - #if MICROPY_PY_UHASHLIB - { MP_ROM_QSTR(MP_QSTR_hashlib), MP_ROM_PTR(&mp_module_uhashlib) }, - #endif - #if MICROPY_PY_UBINASCII && !CIRCUITPY - { MP_ROM_QSTR(MP_QSTR_ubinascii), MP_ROM_PTR(&mp_module_ubinascii) }, - #endif - #if MICROPY_PY_URANDOM - { MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&mp_module_urandom) }, - #endif - #if MICROPY_PY_USELECT - { MP_ROM_QSTR(MP_QSTR_uselect), MP_ROM_PTR(&mp_module_uselect) }, - #endif - #if MICROPY_PY_FRAMEBUF - { MP_ROM_QSTR(MP_QSTR_framebuf), MP_ROM_PTR(&mp_module_framebuf) }, - #endif - #if MICROPY_PY_BTREE - { MP_ROM_QSTR(MP_QSTR_btree), MP_ROM_PTR(&mp_module_btree) }, - #endif - - // extra builtin modules as defined by a port - MICROPY_PORT_BUILTIN_MODULES - - #ifdef MICROPY_REGISTERED_MODULES // builtin modules declared with MP_REGISTER_MODULE() MICROPY_REGISTERED_MODULES - #endif - - #if defined(MICROPY_DEBUG_MODULES) && defined(MICROPY_PORT_BUILTIN_DEBUG_MODULES) - , MICROPY_PORT_BUILTIN_DEBUG_MODULES - #endif }; MP_DEFINE_CONST_MAP(mp_builtin_module_map, mp_builtin_module_table); @@ -324,3 +246,19 @@ STATIC void mp_module_call_init(mp_obj_t module_name, mp_obj_t module_obj) { } } #endif + +void mp_module_generic_attr(qstr attr, mp_obj_t *dest, const uint16_t *keys, mp_obj_t *values) { + for (size_t i = 0; keys[i] != MP_QSTRnull; ++i) { + if (attr == keys[i]) { + if (dest[0] == MP_OBJ_NULL) { + // load attribute (MP_OBJ_NULL returned for deleted items) + dest[0] = values[i]; + } else { + // delete or store (delete stores MP_OBJ_NULL) + values[i] = dest[1]; + dest[0] = MP_OBJ_NULL; // indicate success + } + return; + } + } +} diff --git a/py/objmodule.h b/py/objmodule.h index 5e54dbf3ab259..d11d5bcd746bd 100644 --- a/py/objmodule.h +++ b/py/objmodule.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2019 Damien P. George + * Copyright (c) 2013-2019 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,6 +28,9 @@ #include "py/obj.h" +// Place at the very end of a module's globals_table. +#define MP_MODULE_ATTR_DELEGATION_ENTRY(ptr) { MP_ROM_QSTR(MP_QSTRnull), MP_ROM_PTR(ptr) } + extern const mp_map_t mp_builtin_module_map; mp_obj_t mp_module_get_loaded_or_builtin(qstr module_name); @@ -35,4 +38,6 @@ mp_obj_t mp_module_get_loaded_or_builtin(qstr module_name); mp_obj_t mp_module_get_builtin(qstr module_name); #endif +void mp_module_generic_attr(qstr attr, mp_obj_t *dest, const uint16_t *keys, mp_obj_t *values); + #endif // MICROPY_INCLUDED_PY_OBJMODULE_H diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 60a0a31847ae9..1139ab2b54c30 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h index 4ebefb9d3a51b..b6c37f3909f15 100644 --- a/py/objnamedtuple.h +++ b/py/objnamedtuple.h @@ -1,10 +1,9 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,7 +23,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - #ifndef MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H #define MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H diff --git a/py/objnone.c b/py/objnone.c index 2c33d8902f751..9f6960669aff8 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objobject.c b/py/objobject.c index b32e5fac0d972..32552775aae43 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,8 +38,7 @@ typedef struct _mp_obj_object_t { STATIC mp_obj_t object_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)args; mp_arg_check_num(n_args, n_kw, 0, 0, false); - mp_obj_object_t *o = m_new_obj(mp_obj_object_t); - o->base.type = type; + mp_obj_object_t *o = mp_obj_malloc(mp_obj_object_t, type); return MP_OBJ_FROM_PTR(o); } diff --git a/py/objproperty.c b/py/objproperty.c index f55efc8bdbb66..b0436e5c1f7f0 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -44,8 +44,7 @@ STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); - mp_obj_property_t *o = m_new_obj(mp_obj_property_t); - o->base.type = type; + mp_obj_property_t *o = mp_obj_malloc(mp_obj_property_t, type); o->proxy[0] = vals[ARG_fget].u_obj; o->proxy[1] = vals[ARG_fset].u_obj; o->proxy[2] = vals[ARG_fdel].u_obj; diff --git a/py/objrange.c b/py/objrange.c index 78a5fcd0f8938..d83b55d8267e2 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -97,8 +97,7 @@ STATIC void range_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind STATIC mp_obj_t range_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 3, false); - mp_obj_range_t *o = m_new_obj(mp_obj_range_t); - o->base.type = type; + mp_obj_range_t *o = mp_obj_malloc(mp_obj_range_t, type); o->start = 0; o->step = 1; @@ -173,8 +172,7 @@ STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (mp_obj_is_type(index, &mp_type_slice)) { mp_bound_slice_t slice; mp_seq_get_fast_slice_indexes(len, index, &slice); - mp_obj_range_t *o = m_new_obj(mp_obj_range_t); - o->base.type = &mp_type_range; + mp_obj_range_t *o = mp_obj_malloc(mp_obj_range_t, &mp_type_range); o->start = self->start + slice.start * self->step; o->stop = self->start + slice.stop * self->step; o->step = slice.step * self->step; diff --git a/py/objreversed.c b/py/objreversed.c index fe517cc37f63d..c9b36bf2a48b7 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George + * Copyright (c) 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -47,8 +47,7 @@ STATIC mp_obj_t reversed_make_new(const mp_obj_type_t *type, size_t n_args, size return mp_call_method_n_kw(0, 0, dest); } - mp_obj_reversed_t *o = m_new_obj(mp_obj_reversed_t); - o->base.type = type; + mp_obj_reversed_t *o = mp_obj_malloc(mp_obj_reversed_t, type); o->seq = args[0]; o->cur_index = mp_obj_get_int(mp_obj_len(args[0])); // start at the end of the sequence diff --git a/py/objset.c b/py/objset.c index 237e4c24710d9..9557ec76ab5e0 100644 --- a/py/objset.c +++ b/py/objset.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2017 Damien P. George + * Copyright (c) 2013-2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -176,8 +176,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(set_clear_obj, set_clear); STATIC mp_obj_t set_copy(mp_obj_t self_in) { check_set_or_frozenset(self_in); mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_set_t *other = m_new_obj(mp_obj_set_t); - other->base.type = self->base.type; + mp_obj_set_t *other = mp_obj_malloc(mp_obj_set_t, self->base.type); mp_set_init(&other->set, self->set.alloc); other->set.used = self->set.used; memcpy(other->set.table, self->set.table, self->set.alloc * sizeof(mp_obj_t)); @@ -587,8 +586,7 @@ const mp_obj_type_t mp_type_frozenset = { #endif mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) { - mp_obj_set_t *o = m_new_obj(mp_obj_set_t); - o->base.type = &mp_type_set; + mp_obj_set_t *o = mp_obj_malloc(mp_obj_set_t, &mp_type_set); mp_set_init(&o->set, n_args); for (size_t i = 0; i < n_args; i++) { mp_set_lookup(&o->set, items[i], MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); diff --git a/py/objsingleton.c b/py/objsingleton.c index dfa6876dacc0d..34a6ebd028d89 100644 --- a/py/objsingleton.c +++ b/py/objsingleton.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objslice.c b/py/objslice.c index 395af727e8db1..fe272cfa9b4af 100644 --- a/py/objslice.c +++ b/py/objslice.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -137,8 +137,7 @@ const mp_obj_type_t mp_type_slice = { }; mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) { - mp_obj_slice_t *o = m_new_obj(mp_obj_slice_t); - o->base.type = &mp_type_slice; + mp_obj_slice_t *o = mp_obj_malloc(mp_obj_slice_t, &mp_type_slice); o->start = ostart; o->stop = ostop; o->step = ostep; diff --git a/py/objstr.c b/py/objstr.c index fbb044c65e675..72d44d537cd4c 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -197,7 +197,7 @@ STATIC mp_obj_t bytes_make_new(const mp_obj_type_t *type_in, size_t n_args, size (void)type_in; #if MICROPY_CPYTHON_COMPAT - if (n_kw) { + if (n_kw != 0) { mp_arg_error_unimpl_kw(); } #else @@ -1183,7 +1183,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar s++; } if (*s == '0') { - if (!align) { + if (!align && arg_looks_numeric(arg)) { align = '='; } if (!fill) { @@ -2049,8 +2049,7 @@ const mp_obj_str_t mp_const_empty_bytes_obj = {{&mp_type_bytes}, 0, 0, (const by // the data is copied across. This function should only be used if the type is bytes, // or if the type is str and the string data is known to be not interned. mp_obj_t mp_obj_new_str_copy(const mp_obj_type_t *type, const byte *data, size_t len) { - mp_obj_str_t *o = m_new_obj(mp_obj_str_t); - o->base.type = type; + mp_obj_str_t *o = mp_obj_malloc(mp_obj_str_t, type); o->len = len; if (data) { o->hash = qstr_compute_hash(data, len); @@ -2093,8 +2092,7 @@ mp_obj_t mp_obj_new_str_from_vstr(const mp_obj_type_t *type, vstr_t *vstr) { } // make a new str/bytes object - mp_obj_str_t *o = m_new_obj(mp_obj_str_t); - o->base.type = type; + mp_obj_str_t *o = mp_obj_malloc(mp_obj_str_t, type); o->len = vstr->len; o->hash = qstr_compute_hash((byte *)vstr->buf, vstr->len); if (vstr->len + 1 == vstr->alloc) { diff --git a/py/objstr.h b/py/objstr.h index 8031839146b75..bae32cbffe7a8 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objstringio.c b/py/objstringio.c index c6d22d6c89ee9..563dd149bcd5e 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2017 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2017 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -179,8 +179,7 @@ STATIC mp_obj_t stringio___exit__(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stringio___exit___obj, 4, 4, stringio___exit__); STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) { - mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t); - o->base.type = type; + mp_obj_stringio_t *o = mp_obj_malloc(mp_obj_stringio_t, type); o->pos = 0; o->ref_obj = MP_OBJ_NULL; return o; diff --git a/py/objstringio.h b/py/objstringio.h index 38778f03ae619..56738f4e45439 100644 --- a/py/objstringio.h +++ b/py/objstringio.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George + * Copyright (c) 2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objstrunicode.c b/py/objstrunicode.c index b3b23d0f01afd..93277e630d97d 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2016 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2016 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objtuple.c b/py/objtuple.c index 87d16905df812..275a3e3ed98cc 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -34,7 +34,6 @@ #include "supervisor/shared/translate/translate.h" - /******************************************************************************/ /* tuple */ @@ -253,8 +252,7 @@ mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items) { if (n == 0) { return mp_const_empty_tuple; } - mp_obj_tuple_t *o = m_new_obj_var(mp_obj_tuple_t, mp_obj_t, n); - o->base.type = &mp_type_tuple; + mp_obj_tuple_t *o = mp_obj_malloc_var(mp_obj_tuple_t, mp_obj_t, n, &mp_type_tuple); o->len = n; if (items) { for (size_t i = 0; i < n; i++) { diff --git a/py/objtuple.h b/py/objtuple.h index ded265b47e015..2d3026fca571f 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/objtype.c b/py/objtype.c index 5b04c361e18b0..0d25aac4e9176 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -30,7 +30,6 @@ #include #include -#include "py/gc_long_lived.h" #include "py/objtype.h" #include "py/runtime.h" @@ -123,8 +122,7 @@ STATIC mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_type_t **native_base) { size_t num_native_bases = instance_count_native_bases(class, native_base); assert(num_native_bases < 2); - mp_obj_instance_t *o = m_new_obj_var(mp_obj_instance_t, mp_obj_t, num_native_bases); - o->base.type = class; + mp_obj_instance_t *o = mp_obj_malloc_var(mp_obj_instance_t, mp_obj_t, num_native_bases, class); mp_map_init(&o->members, 0); // Initialise the native base-class slot (should be 1 at most) with a valid // object. It doesn't matter which object, so long as it can be uniquely @@ -588,6 +586,7 @@ retry:; } else if (dest[0] != MP_OBJ_NULL) { dest[2] = rhs_in; res = mp_call_method_n_kw(1, 0, dest); + res = op == MP_BINARY_OP_CONTAINS ? mp_obj_new_bool(mp_obj_is_true(res)) : res; } else { // If this was an inplace method, fallback to normal method // https://docs.python.org/3/reference/datamodel.html#object.__iadd__ : @@ -1202,7 +1201,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) #endif } - mp_obj_full_type_t *o = m_new0_ll(mp_obj_full_type_t, 1); + mp_obj_full_type_t *o = m_new0(mp_obj_full_type_t, 1); o->base.type = &mp_type_type; o->flags = base_flags; o->name = name; @@ -1235,7 +1234,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) } } - o->locals_dict = make_dict_long_lived(MP_OBJ_TO_PTR(locals_dict), 10); + o->locals_dict = MP_OBJ_TO_PTR(locals_dict); #if ENABLE_SPECIAL_ACCESSORS // Check if the class has any special accessor methods diff --git a/py/objzip.c b/py/objzip.c index 91716493d61ff..69aca29e9ae78 100644 --- a/py/objzip.c +++ b/py/objzip.c @@ -39,8 +39,7 @@ typedef struct _mp_obj_zip_t { STATIC mp_obj_t zip_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); - mp_obj_zip_t *o = m_new_obj_var(mp_obj_zip_t, mp_obj_t, n_args); - o->base.type = type; + mp_obj_zip_t *o = mp_obj_malloc_var(mp_obj_zip_t, mp_obj_t, n_args, type); o->n_iters = n_args; for (size_t i = 0; i < n_args; i++) { o->iters[i] = mp_getiter(args[i], NULL); diff --git a/py/parse.c b/py/parse.c index b3be279c5bef5..c8a3b29bb5723 100644 --- a/py/parse.c +++ b/py/parse.c @@ -297,6 +297,16 @@ STATIC void *parser_alloc(parser_t *parser, size_t num_bytes) { } #pragma GCC diagnostic pop +#if MICROPY_COMP_CONST_TUPLE +STATIC void parser_free_parse_node_struct(parser_t *parser, mp_parse_node_struct_t *pns) { + mp_parse_chunk_t *chunk = parser->cur_chunk; + if (chunk->data <= (byte *)pns && (byte *)pns < chunk->data + chunk->union_.used) { + size_t num_bytes = sizeof(mp_parse_node_struct_t) + sizeof(mp_parse_node_t) * MP_PARSE_NODE_STRUCT_NUM_NODES(pns); + chunk->union_.used -= num_bytes; + } +} +#endif + STATIC void push_rule(parser_t *parser, size_t src_line, uint8_t rule_id, size_t arg_i) { if (parser->rule_stack_top >= parser->rule_stack_alloc) { rule_stack_t *rs = m_renew(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc, parser->rule_stack_alloc + MICROPY_ALLOC_PARSE_RULE_INC); @@ -323,6 +333,13 @@ STATIC uint8_t pop_rule(parser_t *parser, size_t *arg_i, size_t *src_line) { return rule_id; } +#if MICROPY_COMP_CONST_TUPLE +STATIC uint8_t peek_rule(parser_t *parser, size_t n) { + assert(parser->rule_stack_top > n); + return parser->rule_stack[parser->rule_stack_top - 1 - n].rule_id; +} +#endif + bool mp_parse_node_is_const_false(mp_parse_node_t pn) { return MP_PARSE_NODE_IS_TOKEN_KIND(pn, MP_TOKEN_KW_FALSE) || (MP_PARSE_NODE_IS_SMALL_INT(pn) && MP_PARSE_NODE_LEAF_SMALL_INT(pn) == 0); @@ -339,18 +356,83 @@ bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o) { return true; } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_const_object)) { mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; - #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D - // nodes are 32-bit pointers, but need to extract 64-bit object - *o = (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32); - #else - *o = (mp_obj_t)pns->nodes[0]; - #endif + *o = mp_parse_node_extract_const_object(pns); return mp_obj_is_int(*o); } else { return false; } } +#if MICROPY_COMP_CONST_TUPLE || MICROPY_COMP_CONST +STATIC bool mp_parse_node_is_const(mp_parse_node_t pn) { + if (MP_PARSE_NODE_IS_SMALL_INT(pn)) { + // Small integer. + return true; + } else if (MP_PARSE_NODE_IS_LEAF(pn)) { + // Possible str, or constant literal. + uintptr_t kind = MP_PARSE_NODE_LEAF_KIND(pn); + if (kind == MP_PARSE_NODE_STRING) { + return true; + } else if (kind == MP_PARSE_NODE_TOKEN) { + uintptr_t arg = MP_PARSE_NODE_LEAF_ARG(pn); + return arg == MP_TOKEN_KW_NONE + || arg == MP_TOKEN_KW_FALSE + || arg == MP_TOKEN_KW_TRUE + || arg == MP_TOKEN_ELLIPSIS; + } + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_const_object)) { + // Constant object. + return true; + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_atom_paren)) { + // Possible empty tuple. + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; + return MP_PARSE_NODE_IS_NULL(pns->nodes[0]); + } + return false; +} + +STATIC mp_obj_t mp_parse_node_convert_to_obj(mp_parse_node_t pn) { + assert(mp_parse_node_is_const(pn)); + if (MP_PARSE_NODE_IS_SMALL_INT(pn)) { + mp_int_t arg = MP_PARSE_NODE_LEAF_SMALL_INT(pn); + #if MICROPY_DYNAMIC_COMPILER + mp_uint_t sign_mask = -((mp_uint_t)1 << (mp_dynamic_compiler.small_int_bits - 1)); + if (!((arg & sign_mask) == 0 || (arg & sign_mask) == sign_mask)) { + // Integer doesn't fit in a small-int, so create a multi-precision int object. + return mp_obj_new_int_from_ll(arg); + } + #endif + return MP_OBJ_NEW_SMALL_INT(arg); + } else if (MP_PARSE_NODE_IS_LEAF(pn)) { + uintptr_t kind = MP_PARSE_NODE_LEAF_KIND(pn); + uintptr_t arg = MP_PARSE_NODE_LEAF_ARG(pn); + if (kind == MP_PARSE_NODE_STRING) { + return MP_OBJ_NEW_QSTR(arg); + } else { + assert(MP_PARSE_NODE_LEAF_KIND(pn) == MP_PARSE_NODE_TOKEN); + switch (arg) { + case MP_TOKEN_KW_NONE: + return mp_const_none; + case MP_TOKEN_KW_FALSE: + return mp_const_false; + case MP_TOKEN_KW_TRUE: + return mp_const_true; + default: + assert(arg == MP_TOKEN_ELLIPSIS); + return MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj); + } + } + } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_const_object)) { + mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; + return mp_parse_node_extract_const_object(pns); + } else { + assert(MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_atom_paren)); + assert(MP_PARSE_NODE_IS_NULL(((mp_parse_node_struct_t *)pn)->nodes[0])); + return mp_const_empty_tuple; + } +} +#endif + size_t mp_parse_node_extract_list(mp_parse_node_t *pn, size_t pn_kind, mp_parse_node_t **nodes) { if (MP_PARSE_NODE_IS_NULL(*pn)) { *nodes = NULL; @@ -394,9 +476,6 @@ void mp_parse_node_print(const mp_print_t *print, mp_parse_node_t pn, size_t ind case MP_PARSE_NODE_STRING: mp_printf(print, "str(%s)\n", qstr_str(arg)); break; - case MP_PARSE_NODE_BYTES: - mp_printf(print, "bytes(%s)\n", qstr_str(arg)); - break; default: assert(MP_PARSE_NODE_LEAF_KIND(pn) == MP_PARSE_NODE_TOKEN); mp_printf(print, "tok(%u)\n", (uint)arg); @@ -406,11 +485,14 @@ void mp_parse_node_print(const mp_print_t *print, mp_parse_node_t pn, size_t ind // node must be a mp_parse_node_struct_t mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_const_object) { + mp_obj_t obj = mp_parse_node_extract_const_object(pns); #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D - mp_printf(print, "literal const(%016llx)\n", (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32)); + mp_printf(print, "literal const(%016llx)=", obj); #else - mp_printf(print, "literal const(%p)\n", (mp_obj_t)pns->nodes[0]); + mp_printf(print, "literal const(%p)=", obj); #endif + mp_obj_print_helper(print, obj, PRINT_REPR); + mp_printf(print, "\n"); } else { size_t n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns); #if MICROPY_DEBUG_PARSE_RULE_NAME @@ -469,16 +551,28 @@ STATIC mp_parse_node_t make_node_const_object(parser_t *parser, size_t src_line, return (mp_parse_node_t)pn; } -STATIC mp_parse_node_t mp_parse_node_new_small_int_checked(parser_t *parser, mp_obj_t o_val) { - (void)parser; - mp_int_t val = MP_OBJ_SMALL_INT_VALUE(o_val); - #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D - // A parse node is only 32-bits and the small-int value must fit in 31-bits - if (((val ^ (val << 1)) & 0xffffffff80000000) != 0) { - return make_node_const_object(parser, 0, o_val); +// Create a parse node representing a constant object, possibly optimising the case of +// an integer, by putting the (small) integer value directly in the parse node itself. +STATIC mp_parse_node_t make_node_const_object_optimised(parser_t *parser, size_t src_line, mp_obj_t obj) { + if (mp_obj_is_small_int(obj)) { + mp_int_t val = MP_OBJ_SMALL_INT_VALUE(obj); + #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D + // A parse node is only 32-bits and the small-int value must fit in 31-bits + if (((val ^ (val << 1)) & 0xffffffff80000000) != 0) { + return make_node_const_object(parser, src_line, obj); + } + #endif + #if MICROPY_DYNAMIC_COMPILER + // Check that the integer value fits in target runtime's small-int + mp_uint_t sign_mask = -((mp_uint_t)1 << (mp_dynamic_compiler.small_int_bits - 1)); + if (!((val & sign_mask) == 0 || (val & sign_mask) == sign_mask)) { + return make_node_const_object(parser, src_line, obj); + } + #endif + return mp_parse_node_new_small_int(val); + } else { + return make_node_const_object(parser, src_line, obj); } - #endif - return mp_parse_node_new_small_int(val); } STATIC void push_result_token(parser_t *parser, uint8_t rule_id) { @@ -491,11 +585,7 @@ STATIC void push_result_token(parser_t *parser, uint8_t rule_id) { mp_map_elem_t *elem; if (rule_id == RULE_atom && (elem = mp_map_lookup(&parser->consts, MP_OBJ_NEW_QSTR(id), MP_MAP_LOOKUP)) != NULL) { - if (mp_obj_is_small_int(elem->value)) { - pn = mp_parse_node_new_small_int_checked(parser, elem->value); - } else { - pn = make_node_const_object(parser, lex->tok_line, elem->value); - } + pn = make_node_const_object_optimised(parser, lex->tok_line, elem->value); } else { pn = mp_parse_node_new_leaf(MP_PARSE_NODE_ID, id); } @@ -505,16 +595,12 @@ STATIC void push_result_token(parser_t *parser, uint8_t rule_id) { #endif } else if (lex->tok_kind == MP_TOKEN_INTEGER) { mp_obj_t o = mp_parse_num_integer(lex->vstr.buf, lex->vstr.len, 0, lex); - if (mp_obj_is_small_int(o)) { - pn = mp_parse_node_new_small_int_checked(parser, o); - } else { - pn = make_node_const_object(parser, lex->tok_line, o); - } + pn = make_node_const_object_optimised(parser, lex->tok_line, o); } else if (lex->tok_kind == MP_TOKEN_FLOAT_OR_IMAG) { mp_obj_t o = mp_parse_num_decimal(lex->vstr.buf, lex->vstr.len, true, false, lex); pn = make_node_const_object(parser, lex->tok_line, o); - } else if (lex->tok_kind == MP_TOKEN_STRING || lex->tok_kind == MP_TOKEN_BYTES) { - // Don't automatically intern all strings/bytes. doc strings (which are usually large) + } else if (lex->tok_kind == MP_TOKEN_STRING) { + // Don't automatically intern all strings. Doc strings (which are usually large) // will be discarded by the compiler, and so we shouldn't intern them. qstr qst = MP_QSTRnull; if (lex->vstr.len <= MICROPY_ALLOC_PARSE_INTERN_STRING_LEN) { @@ -526,14 +612,16 @@ STATIC void push_result_token(parser_t *parser, uint8_t rule_id) { } if (qst != MP_QSTRnull) { // qstr exists, make a leaf node - pn = mp_parse_node_new_leaf(lex->tok_kind == MP_TOKEN_STRING ? MP_PARSE_NODE_STRING : MP_PARSE_NODE_BYTES, qst); + pn = mp_parse_node_new_leaf(MP_PARSE_NODE_STRING, qst); } else { - // not interned, make a node holding a pointer to the string/bytes object - mp_obj_t o = mp_obj_new_str_copy( - lex->tok_kind == MP_TOKEN_STRING ? &mp_type_str : &mp_type_bytes, - (const byte *)lex->vstr.buf, lex->vstr.len); + // not interned, make a node holding a pointer to the string object + mp_obj_t o = mp_obj_new_str_copy(&mp_type_str, (const byte *)lex->vstr.buf, lex->vstr.len); pn = make_node_const_object(parser, lex->tok_line, o); } + } else if (lex->tok_kind == MP_TOKEN_BYTES) { + // make a node holding a pointer to the bytes object + mp_obj_t o = mp_obj_new_bytes((const byte *)lex->vstr.buf, lex->vstr.len); + pn = make_node_const_object(parser, lex->tok_line, o); } else { pn = mp_parse_node_new_leaf(MP_PARSE_NODE_TOKEN, lex->tok_kind); } @@ -557,6 +645,17 @@ STATIC MP_DEFINE_CONST_MAP(mp_constants_map, mp_constants_table); STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id, size_t num_args); #if MICROPY_COMP_CONST_FOLDING +// CIRCUITPY: The compilers mentioned below are esp-2020r3. We are using minimum esp-2021r3 (ESP-IDF v4.4). +// See https://github.com/micropython/micropython/commit/f63b4f85aae1e0ade7a7c9f908debb5905cc144d +// and https://github.com/espressif/esp-idf/issues/9130 +// So disable this for CircuitPython. +/* +#if MICROPY_COMP_CONST_FOLDING_COMPILER_WORKAROUND +// Some versions of the xtensa-esp32-elf-gcc compiler generate wrong code if this +// function is static, so provide a hook for them to work around this problem. +MP_NOINLINE +#endif +*/ STATIC bool fold_logical_constants(parser_t *parser, uint8_t rule_id, size_t *num_args) { if (rule_id == RULE_or_test || rule_id == RULE_and_test) { @@ -721,14 +820,14 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { // get the value mp_parse_node_t pn_value = ((mp_parse_node_struct_t *)((mp_parse_node_struct_t *)pn1)->nodes[1])->nodes[0]; - mp_obj_t value; - if (!mp_parse_node_get_int_maybe(pn_value, &value)) { + if (!mp_parse_node_is_const(pn_value)) { mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, - MP_ERROR_TEXT("constant must be an integer")); + MP_ERROR_TEXT("not a constant")); mp_obj_exception_add_traceback(exc, parser->lexer->source_name, ((mp_parse_node_struct_t *)pn1)->source_line, MP_QSTRnull); nlr_raise(exc); } + mp_obj_t value = mp_parse_node_convert_to_obj(pn_value); // store the value in the table of dynamic constants mp_map_elem_t *elem = mp_map_lookup(&parser->consts, MP_OBJ_NEW_QSTR(id), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); @@ -790,17 +889,65 @@ STATIC bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { for (size_t i = num_args; i > 0; i--) { pop_result(parser); } - if (mp_obj_is_small_int(arg0)) { - push_result_node(parser, mp_parse_node_new_small_int_checked(parser, arg0)); - } else { - // TODO reuse memory for parse node struct? - push_result_node(parser, make_node_const_object(parser, 0, arg0)); - } + push_result_node(parser, make_node_const_object_optimised(parser, 0, arg0)); return true; } #endif +#if MICROPY_COMP_CONST_TUPLE +STATIC bool build_tuple_from_stack(parser_t *parser, size_t src_line, size_t num_args) { + for (size_t i = num_args; i > 0;) { + mp_parse_node_t pn = peek_result(parser, --i); + if (!mp_parse_node_is_const(pn)) { + return false; + } + } + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(num_args, NULL)); + for (size_t i = num_args; i > 0;) { + mp_parse_node_t pn = pop_result(parser); + tuple->items[--i] = mp_parse_node_convert_to_obj(pn); + if (MP_PARSE_NODE_IS_STRUCT(pn)) { + parser_free_parse_node_struct(parser, (mp_parse_node_struct_t *)pn); + } + } + push_result_node(parser, make_node_const_object(parser, src_line, MP_OBJ_FROM_PTR(tuple))); + return true; +} + +STATIC bool build_tuple(parser_t *parser, size_t src_line, uint8_t rule_id, size_t num_args) { + if (rule_id == RULE_testlist_comp) { + if (peek_rule(parser, 0) == RULE_atom_paren) { + // Tuple of the form "(a,)". + return build_tuple_from_stack(parser, src_line, num_args); + } + } + if (rule_id == RULE_testlist_comp_3c) { + assert(peek_rule(parser, 0) == RULE_testlist_comp_3b); + assert(peek_rule(parser, 1) == RULE_testlist_comp); + if (peek_rule(parser, 2) == RULE_atom_paren) { + // Tuple of the form "(a, b)". + if (build_tuple_from_stack(parser, src_line, num_args)) { + parser->rule_stack_top -= 2; // discard 2 rules + return true; + } + } + } + if (rule_id == RULE_testlist_star_expr + || rule_id == RULE_testlist + || rule_id == RULE_subscriptlist) { + // Tuple of the form: + // - x = a, b + // - return a, b + // - for x in a, b: pass + // - x[a, b] + return build_tuple_from_stack(parser, src_line, num_args); + } + + return false; +} +#endif + STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id, size_t num_args) { // Simplify and optimise certain rules, to reduce memory usage and simplify the compiler. if (rule_id == RULE_atom_paren) { @@ -857,6 +1004,13 @@ STATIC void push_result_rule(parser_t *parser, size_t src_line, uint8_t rule_id, } #endif + #if MICROPY_COMP_CONST_TUPLE + if (build_tuple(parser, src_line, rule_id, num_args)) { + // we built a tuple from this rule so return straight away + return; + } + #endif + mp_parse_node_struct_t *pn = parser_alloc(parser, sizeof(mp_parse_node_struct_t) + sizeof(mp_parse_node_t) * num_args); pn->source_line = src_line; pn->kind_num_nodes = (rule_id & 0xff) | (num_args << 8); diff --git a/py/parse.h b/py/parse.h index 5f1e30c2ff140..d9d0e1531476d 100644 --- a/py/parse.h +++ b/py/parse.h @@ -39,15 +39,13 @@ struct _mp_lexer_t; // - xxxx...xx00: pointer to mp_parse_node_struct_t // - xx...xx0010: an identifier; bits 4 and above are the qstr // - xx...xx0110: a string; bits 4 and above are the qstr holding the value -// - xx...xx1010: a string of bytes; bits 4 and above are the qstr holding the value -// - xx...xx1110: a token; bits 4 and above are mp_token_kind_t +// - xx...xx1010: a token; bits 4 and above are mp_token_kind_t #define MP_PARSE_NODE_NULL (0) #define MP_PARSE_NODE_SMALL_INT (0x1) #define MP_PARSE_NODE_ID (0x02) #define MP_PARSE_NODE_STRING (0x06) -#define MP_PARSE_NODE_BYTES (0x0a) -#define MP_PARSE_NODE_TOKEN (0x0e) +#define MP_PARSE_NODE_TOKEN (0x0a) typedef uintptr_t mp_parse_node_t; // must be pointer size @@ -79,9 +77,20 @@ typedef struct _mp_parse_node_struct_t { static inline mp_parse_node_t mp_parse_node_new_small_int(mp_int_t val) { return (mp_parse_node_t)(MP_PARSE_NODE_SMALL_INT | ((mp_uint_t)val << 1)); } + static inline mp_parse_node_t mp_parse_node_new_leaf(size_t kind, mp_int_t arg) { return (mp_parse_node_t)(kind | ((mp_uint_t)arg << 4)); } + +static inline mp_obj_t mp_parse_node_extract_const_object(mp_parse_node_struct_t *pns) { + #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D + // nodes are 32-bit pointers, but need to extract 64-bit object + return (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32); + #else + return (mp_obj_t)pns->nodes[0]; + #endif +} + bool mp_parse_node_is_const_false(mp_parse_node_t pn); bool mp_parse_node_is_const_true(mp_parse_node_t pn); bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o); diff --git a/py/persistentcode.c b/py/persistentcode.c index 0431b30a29586..272298274f8ee 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -36,8 +36,6 @@ #include "py/objstr.h" #include "py/mpthread.h" -#include "supervisor/shared/translate/translate.h" - #if MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE #include "py/smallint.h" @@ -50,72 +48,6 @@ #define MPY_FEATURE_ARCH_DYNAMIC MPY_FEATURE_ARCH #endif -#if MICROPY_PERSISTENT_CODE_LOAD || (MICROPY_PERSISTENT_CODE_SAVE && !MICROPY_DYNAMIC_COMPILER) -// The bytecode will depend on the number of bits in a small-int, and -// this function computes that (could make it a fixed constant, but it -// would need to be defined in mpconfigport.h). -STATIC int mp_small_int_bits(void) { - mp_int_t i = MP_SMALL_INT_MAX; - int n = 1; - while (i != 0) { - i >>= 1; - ++n; - } - return n; -} -#endif - -#define QSTR_WINDOW_SIZE (32) - -typedef struct _qstr_window_t { - uint16_t idx; // indexes the head of the window - uint16_t window[QSTR_WINDOW_SIZE]; -} qstr_window_t; - -// Push a qstr to the head of the window, and the tail qstr is overwritten -STATIC void qstr_window_push(qstr_window_t *qw, qstr qst) { - qw->idx = (qw->idx + 1) % QSTR_WINDOW_SIZE; - qw->window[qw->idx] = qst; -} - -// Pull an existing qstr from within the window to the head of the window -STATIC qstr qstr_window_pull(qstr_window_t *qw, size_t idx) { - qstr qst = qw->window[idx]; - if (idx > qw->idx) { - memmove(&qw->window[idx], &qw->window[idx + 1], (QSTR_WINDOW_SIZE - idx - 1) * sizeof(uint16_t)); - qw->window[QSTR_WINDOW_SIZE - 1] = qw->window[0]; - idx = 0; - } - memmove(&qw->window[idx], &qw->window[idx + 1], (qw->idx - idx) * sizeof(uint16_t)); - qw->window[qw->idx] = qst; - return qst; -} - -#if MICROPY_PERSISTENT_CODE_LOAD - -// Access a qstr at the given index, relative to the head of the window (0=head) -STATIC qstr qstr_window_access(qstr_window_t *qw, size_t idx) { - return qstr_window_pull(qw, (qw->idx + QSTR_WINDOW_SIZE - idx) % QSTR_WINDOW_SIZE); -} - -#endif - -#if MICROPY_PERSISTENT_CODE_SAVE - -// Insert a qstr at the head of the window, either by pulling an existing one or pushing a new one -STATIC size_t qstr_window_insert(qstr_window_t *qw, qstr qst) { - for (size_t idx = 0; idx < QSTR_WINDOW_SIZE; ++idx) { - if (qw->window[idx] == qst) { - qstr_window_pull(qw, idx); - return (qw->idx + QSTR_WINDOW_SIZE - idx) % QSTR_WINDOW_SIZE; - } - } - qstr_window_push(qw, qst); - return QSTR_WINDOW_SIZE; -} - -#endif - typedef struct _bytecode_prelude_t { uint n_state; uint n_exc_stack; @@ -126,88 +58,33 @@ typedef struct _bytecode_prelude_t { uint code_info_size; } bytecode_prelude_t; -// ip will point to start of opcodes -// return value will point to simple_name, source_file qstrs -STATIC byte *extract_prelude(const byte **ip, bytecode_prelude_t *prelude) { - MP_BC_PRELUDE_SIG_DECODE(*ip); - prelude->n_state = n_state; - prelude->n_exc_stack = n_exc_stack; - prelude->scope_flags = scope_flags; - prelude->n_pos_args = n_pos_args; - prelude->n_kwonly_args = n_kwonly_args; - prelude->n_def_pos_args = n_def_pos_args; - MP_BC_PRELUDE_SIZE_DECODE(*ip); - byte *ip_info = (byte *)*ip; - *ip += n_info; - *ip += n_cell; - return ip_info; -} - #endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_LOAD #include "py/parsenum.h" -STATIC void raise_corrupt_mpy(void) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Corrupt .mpy file")); -} - STATIC int read_byte(mp_reader_t *reader); -STATIC size_t read_uint(mp_reader_t *reader, byte **out); +STATIC size_t read_uint(mp_reader_t *reader); #if MICROPY_EMIT_MACHINE_CODE typedef struct _reloc_info_t { mp_reader_t *reader; - mp_uint_t *const_table; + mp_module_context_t *context; + uint8_t *rodata; + uint8_t *bss; } reloc_info_t; -#if MICROPY_EMIT_THUMB -STATIC void asm_thumb_rewrite_mov(uint8_t *pc, uint16_t val) { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wcast-align" - // high part - *(uint16_t *)pc = (*(uint16_t *)pc & 0xfbf0) | (val >> 1 & 0x0400) | (val >> 12); - // low part - *(uint16_t *)(pc + 2) = (*(uint16_t *)(pc + 2) & 0x0f00) | (val << 4 & 0x7000) | (val & 0x00ff); - #pragma GCC diagnostic pop -} -#endif - -STATIC void arch_link_qstr(uint8_t *pc, bool is_obj, qstr qst) { - mp_uint_t val = qst; - if (is_obj) { - val = (mp_uint_t)MP_OBJ_NEW_QSTR(qst); - } - #if MICROPY_EMIT_X86 || MICROPY_EMIT_X64 || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA || MICROPY_EMIT_XTENSAWIN - pc[0] = val & 0xff; - pc[1] = (val >> 8) & 0xff; - pc[2] = (val >> 16) & 0xff; - pc[3] = (val >> 24) & 0xff; - #elif MICROPY_EMIT_THUMB - if (is_obj) { - // qstr object, movw and movt - asm_thumb_rewrite_mov(pc, val); // movw - asm_thumb_rewrite_mov(pc + 4, val >> 16); // movt - } else { - // qstr number, movw instruction - asm_thumb_rewrite_mov(pc, val); // movw - } - #endif -} - void mp_native_relocate(void *ri_in, uint8_t *text, uintptr_t reloc_text) { // Relocate native code reloc_info_t *ri = ri_in; + uint8_t op; uintptr_t *addr_to_adjust = NULL; - - // Read the byte directly so that we don't error on EOF. - mp_uint_t op = ri->reader->readbyte(ri->reader->data); - while (op != 0xff && op != MP_READER_EOF) { + while ((op = read_byte(ri->reader)) != 0xff) { if (op & 1) { // Point to new location to make adjustments - size_t addr = read_uint(ri->reader, NULL); + size_t addr = read_uint(ri->reader); if ((addr & 1) == 0) { // Point to somewhere in text #pragma GCC diagnostic push @@ -216,7 +93,10 @@ void mp_native_relocate(void *ri_in, uint8_t *text, uintptr_t reloc_text) { #pragma GCC diagnostic pop } else { // Point to somewhere in rodata - addr_to_adjust = &((uintptr_t *)ri->const_table[1])[addr >> 1]; + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" + addr_to_adjust = &((uintptr_t *)ri->rodata)[addr >> 1]; + #pragma GCC diagnostic pop } } op >>= 1; @@ -225,61 +105,54 @@ void mp_native_relocate(void *ri_in, uint8_t *text, uintptr_t reloc_text) { if (op <= 5) { if (op & 1) { // Read in number of adjustments to make - n = read_uint(ri->reader, NULL); + n = read_uint(ri->reader); } op >>= 1; if (op == 0) { // Destination is text dest = reloc_text; + } else if (op == 1) { + // Destination is rodata + dest = (uintptr_t)ri->rodata; } else { - // Destination is rodata (op=1) or bss (op=1 if no rodata, else op=2) - dest = ri->const_table[op]; + // Destination is bss + dest = (uintptr_t)ri->bss; } } else if (op == 6) { + // Destination is qstr_table + dest = (uintptr_t)ri->context->constants.qstr_table; + } else if (op == 7) { + // Destination is obj_table + dest = (uintptr_t)ri->context->constants.obj_table; + } else if (op == 8) { // Destination is mp_fun_table itself dest = (uintptr_t)&mp_fun_table; } else { // Destination is an entry in mp_fun_table - dest = ((uintptr_t *)&mp_fun_table)[op - 7]; + dest = ((uintptr_t *)&mp_fun_table)[op - 9]; } while (n--) { *addr_to_adjust++ += dest; } - op = ri->reader->readbyte(ri->reader->data); } } #endif STATIC int read_byte(mp_reader_t *reader) { - mp_uint_t b = reader->readbyte(reader->data); - if (b == MP_READER_EOF) { - raise_corrupt_mpy(); - } - return b; + return reader->readbyte(reader->data); } STATIC void read_bytes(mp_reader_t *reader, byte *buf, size_t len) { while (len-- > 0) { - mp_uint_t b = reader->readbyte(reader->data); - if (b == MP_READER_EOF) { - raise_corrupt_mpy(); - } - *buf++ = b; + *buf++ = reader->readbyte(reader->data); } } -STATIC size_t read_uint(mp_reader_t *reader, byte **out) { +STATIC size_t read_uint(mp_reader_t *reader) { size_t unum = 0; for (;;) { - mp_uint_t b = reader->readbyte(reader->data); - if (b == MP_READER_EOF) { - raise_corrupt_mpy(); - } - if (out != NULL) { - **out = b; - ++*out; - } + byte b = reader->readbyte(reader->data); unum = (unum << 7) | (b & 0x7f); if ((b & 0x80) == 0) { break; @@ -288,122 +161,89 @@ STATIC size_t read_uint(mp_reader_t *reader, byte **out) { return unum; } -STATIC qstr load_qstr(mp_reader_t *reader, qstr_window_t *qw) { - size_t len = read_uint(reader, NULL); - if (len == 0) { - // static qstr - return read_byte(reader); - } +STATIC qstr load_qstr(mp_reader_t *reader) { + size_t len = read_uint(reader); if (len & 1) { - // qstr in window - return qstr_window_access(qw, len >> 1); + // static qstr + return len >> 1; } len >>= 1; char *str = m_new(char, len); read_bytes(reader, (byte *)str, len); + read_byte(reader); // read and discard null terminator qstr qst = qstr_from_strn(str, len); m_del(char, str, len); - qstr_window_push(qw, qst); return qst; } STATIC mp_obj_t load_obj(mp_reader_t *reader) { byte obj_type = read_byte(reader); - if (obj_type == 'e') { + #if MICROPY_EMIT_MACHINE_CODE + if (obj_type == MP_PERSISTENT_OBJ_FUN_TABLE) { + return MP_OBJ_FROM_PTR(&mp_fun_table); + } else + #endif + if (obj_type == MP_PERSISTENT_OBJ_NONE) { + return mp_const_none; + } else if (obj_type == MP_PERSISTENT_OBJ_FALSE) { + return mp_const_false; + } else if (obj_type == MP_PERSISTENT_OBJ_TRUE) { + return mp_const_true; + } else if (obj_type == MP_PERSISTENT_OBJ_ELLIPSIS) { return MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj); } else { - size_t len = read_uint(reader, NULL); + size_t len = read_uint(reader); + if (len == 0 && obj_type == MP_PERSISTENT_OBJ_BYTES) { + read_byte(reader); // skip null terminator + return mp_const_empty_bytes; + } else if (obj_type == MP_PERSISTENT_OBJ_TUPLE) { + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL)); + for (size_t i = 0; i < len; ++i) { + tuple->items[i] = load_obj(reader); + } + return MP_OBJ_FROM_PTR(tuple); + } vstr_t vstr; vstr_init_len(&vstr, len); read_bytes(reader, (byte *)vstr.buf, len); - if (obj_type == 's' || obj_type == 'b') { - return mp_obj_new_str_from_vstr(obj_type == 's' ? &mp_type_str : &mp_type_bytes, &vstr); - } else if (obj_type == 'i') { + if (obj_type == MP_PERSISTENT_OBJ_STR || obj_type == MP_PERSISTENT_OBJ_BYTES) { + read_byte(reader); // skip null terminator + return mp_obj_new_str_from_vstr(obj_type == MP_PERSISTENT_OBJ_STR ? &mp_type_str : &mp_type_bytes, &vstr); + } else if (obj_type == MP_PERSISTENT_OBJ_INT) { return mp_parse_num_integer(vstr.buf, vstr.len, 10, NULL); } else { - assert(obj_type == 'f' || obj_type == 'c'); - return mp_parse_num_decimal(vstr.buf, vstr.len, obj_type == 'c', false, NULL); + assert(obj_type == MP_PERSISTENT_OBJ_FLOAT || obj_type == MP_PERSISTENT_OBJ_COMPLEX); + return mp_parse_num_decimal(vstr.buf, vstr.len, obj_type == MP_PERSISTENT_OBJ_COMPLEX, false, NULL); } } } -STATIC void load_prelude_qstrs(mp_reader_t *reader, qstr_window_t *qw, byte *ip) { - qstr simple_name = load_qstr(reader, qw); - ip[0] = simple_name; - ip[1] = simple_name >> 8; - qstr source_file = load_qstr(reader, qw); - ip[2] = source_file; - ip[3] = source_file >> 8; -} - -STATIC void load_prelude(mp_reader_t *reader, qstr_window_t *qw, byte **ip, bytecode_prelude_t *prelude) { - // Read in the prelude header - byte *ip_read = *ip; - read_uint(reader, &ip_read); // read in n_state/etc (is effectively a var-uint) - read_uint(reader, &ip_read); // read in n_info/n_cell (is effectively a var-uint) - - // Prelude header has been read into *ip, now decode and extract values from it - extract_prelude((const byte **)ip, prelude); - - // Load qstrs in prelude - load_prelude_qstrs(reader, qw, ip_read); - ip_read += 4; - - // Read remaining code info - read_bytes(reader, ip_read, *ip - ip_read); -} - -STATIC void load_bytecode(mp_reader_t *reader, qstr_window_t *qw, byte *ip, byte *ip_top) { - while (ip < ip_top) { - *ip = read_byte(reader); - size_t sz; - uint f = mp_opcode_format(ip, &sz, false); - ++ip; - --sz; - if (f == MP_BC_FORMAT_QSTR) { - qstr qst = load_qstr(reader, qw); - *ip++ = qst; - *ip++ = qst >> 8; - sz -= 2; - } else if (f == MP_BC_FORMAT_VAR_UINT) { - while ((*ip++ = read_byte(reader)) & 0x80) { - } - } - read_bytes(reader, ip, sz); - ip += sz; - } -} - -STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { +STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *context) { // Load function kind and data length - size_t kind_len = read_uint(reader, NULL); + size_t kind_len = read_uint(reader); int kind = (kind_len & 3) + MP_CODE_BYTECODE; - size_t fun_data_len = kind_len >> 2; + bool has_children = !!(kind_len & 4); + size_t fun_data_len = kind_len >> 3; #if !MICROPY_EMIT_MACHINE_CODE if (kind != MP_CODE_BYTECODE) { - + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); } #endif uint8_t *fun_data = NULL; - bytecode_prelude_t prelude = {0}; #if MICROPY_EMIT_MACHINE_CODE size_t prelude_offset = 0; - mp_uint_t type_sig = 0; - size_t n_qstr_link = 0; + mp_uint_t native_scope_flags = 0; + mp_uint_t native_n_pos_args = 0; + mp_uint_t native_type_sig = 0; #endif if (kind == MP_CODE_BYTECODE) { // Allocate memory for the bytecode fun_data = m_new(uint8_t, fun_data_len); - - // Load prelude - byte *ip = fun_data; - load_prelude(reader, qw, &ip, &prelude); - // Load bytecode - load_bytecode(reader, qw, ip, fun_data + fun_data_len); + read_bytes(reader, fun_data, fun_data_len); #if MICROPY_EMIT_MACHINE_CODE } else { @@ -412,138 +252,104 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { MP_PLAT_ALLOC_EXEC(fun_data_len, (void **)&fun_data, &fun_alloc); read_bytes(reader, fun_data, fun_data_len); - if (kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER) { - // Parse qstr link table and link native code - n_qstr_link = read_uint(reader, NULL); - for (size_t i = 0; i < n_qstr_link; ++i) { - size_t off = read_uint(reader, NULL); - qstr qst = load_qstr(reader, qw); - uint8_t *dest = fun_data + (off >> 2); - if ((off & 3) == 0) { - // Generic 16-bit link - dest[0] = qst & 0xff; - dest[1] = (qst >> 8) & 0xff; - } else if ((off & 3) == 3) { - // Generic, aligned qstr-object link - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wcast-align" - *(mp_obj_t *)dest = MP_OBJ_NEW_QSTR(qst); - #pragma GCC diagnostic pop - } else { - // Architecture-specific link - arch_link_qstr(dest, (off & 3) == 2, qst); - } - } - } - if (kind == MP_CODE_NATIVE_PY) { - // Extract prelude for later use - prelude_offset = read_uint(reader, NULL); + // Read prelude offset within fun_data, and extract scope flags. + prelude_offset = read_uint(reader); const byte *ip = fun_data + prelude_offset; - byte *ip_info = extract_prelude(&ip, &prelude); - // Load qstrs in prelude - load_prelude_qstrs(reader, qw, ip_info); + MP_BC_PRELUDE_SIG_DECODE(ip); + native_scope_flags = scope_flags; } else { - // Load basic scope info for viper and asm - prelude.scope_flags = read_uint(reader, NULL); - prelude.n_pos_args = 0; - prelude.n_kwonly_args = 0; + // Load basic scope info for viper and asm. + native_scope_flags = read_uint(reader); if (kind == MP_CODE_NATIVE_ASM) { - prelude.n_pos_args = read_uint(reader, NULL); - type_sig = read_uint(reader, NULL); + native_n_pos_args = read_uint(reader); + native_type_sig = read_uint(reader); } } #endif } - size_t n_obj = 0; - size_t n_raw_code = 0; - mp_uint_t *const_table = NULL; - - if (kind != MP_CODE_NATIVE_ASM) { - // Load constant table for bytecode, native and viper + size_t n_children = 0; + mp_raw_code_t **children = NULL; - // Number of entries in constant table - n_obj = read_uint(reader, NULL); - n_raw_code = read_uint(reader, NULL); - - // Allocate constant table - size_t n_alloc = prelude.n_pos_args + prelude.n_kwonly_args + n_obj + n_raw_code; - #if MICROPY_EMIT_MACHINE_CODE - if (kind != MP_CODE_BYTECODE) { - ++n_alloc; // additional entry for mp_fun_table - if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRODATA) { - ++n_alloc; // additional entry for rodata - } - if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERBSS) { - ++n_alloc; // additional entry for BSS - } + #if MICROPY_EMIT_MACHINE_CODE + // Load optional BSS/rodata for viper. + uint8_t *rodata = NULL; + uint8_t *bss = NULL; + if (kind == MP_CODE_NATIVE_VIPER) { + size_t rodata_size = 0; + if (native_scope_flags & MP_SCOPE_FLAG_VIPERRODATA) { + rodata_size = read_uint(reader); } - #endif - - const_table = m_new(mp_uint_t, n_alloc); - mp_uint_t *ct = const_table; - // Load function argument names (initial entries in const_table) - // (viper has n_pos_args=n_kwonly_args=0 so doesn't load any qstrs here) - for (size_t i = 0; i < prelude.n_pos_args + prelude.n_kwonly_args; ++i) { - *ct++ = (mp_uint_t)MP_OBJ_NEW_QSTR(load_qstr(reader, qw)); + size_t bss_size = 0; + if (native_scope_flags & MP_SCOPE_FLAG_VIPERBSS) { + bss_size = read_uint(reader); } - #if MICROPY_EMIT_MACHINE_CODE - if (kind != MP_CODE_BYTECODE) { - // Populate mp_fun_table entry - *ct++ = (mp_uint_t)(uintptr_t)&mp_fun_table; - - // Allocate and load rodata if needed - if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRODATA) { - size_t size = read_uint(reader, NULL); - uint8_t *rodata = m_new(uint8_t, size); - read_bytes(reader, rodata, size); - *ct++ = (uintptr_t)rodata; + if (rodata_size + bss_size != 0) { + bss_size = (uintptr_t)MP_ALIGN(bss_size, sizeof(uintptr_t)); + uint8_t *data = m_new0(uint8_t, bss_size + rodata_size); + bss = data; + rodata = bss + bss_size; + if (native_scope_flags & MP_SCOPE_FLAG_VIPERRODATA) { + read_bytes(reader, rodata, rodata_size); } - // Allocate BSS if needed - if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERBSS) { - size_t size = read_uint(reader, NULL); - uint8_t *bss = m_new0(uint8_t, size); - *ct++ = (uintptr_t)bss; - } + // Viper code with BSS/rodata should not have any children. + // Reuse the children pointer to reference the BSS/rodata + // memory so that it is not reclaimed by the GC. + assert(!has_children); + children = (void *)data; } - #endif + } + #endif - // Load constant objects and raw code children - for (size_t i = 0; i < n_obj; ++i) { - *ct++ = (mp_uint_t)load_obj(reader); - } - for (size_t i = 0; i < n_raw_code; ++i) { - *ct++ = (mp_uint_t)(uintptr_t)load_raw_code(reader, qw); + // Load children if any. + if (has_children) { + n_children = read_uint(reader); + children = m_new(mp_raw_code_t *, n_children + (kind == MP_CODE_NATIVE_PY)); + for (size_t i = 0; i < n_children; ++i) { + children[i] = load_raw_code(reader, context); } } // Create raw_code and return it mp_raw_code_t *rc = mp_emit_glue_new_raw_code(); if (kind == MP_CODE_BYTECODE) { + const byte *ip = fun_data; + MP_BC_PRELUDE_SIG_DECODE(ip); // Assign bytecode to raw code object mp_emit_glue_assign_bytecode(rc, fun_data, #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS fun_data_len, #endif - const_table, + children, #if MICROPY_PERSISTENT_CODE_SAVE - n_obj, n_raw_code, + n_children, #endif - prelude.scope_flags); + scope_flags); #if MICROPY_EMIT_MACHINE_CODE } else { + const uint8_t *prelude_ptr; + #if MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE + if (kind == MP_CODE_NATIVE_PY) { + // Executable code cannot be accessed byte-wise on this architecture, so copy + // the prelude to a separate memory region that is byte-wise readable. + void *buf = fun_data + prelude_offset; + size_t n = fun_data_len - prelude_offset; + prelude_ptr = memcpy(m_new(uint8_t, n), buf, n); + } + #endif + // Relocate and commit code to executable address space - reloc_info_t ri = {reader, const_table}; + reloc_info_t ri = {reader, context, rodata, bss}; #if defined(MP_PLAT_COMMIT_EXEC) - void *opt_ri = (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRELOC) ? &ri : NULL; + void *opt_ri = (native_scope_flags & MP_SCOPE_FLAG_VIPERRELOC) ? &ri : NULL; fun_data = MP_PLAT_COMMIT_EXEC(fun_data, fun_data_len, opt_ri); #else - if (prelude.scope_flags & MP_SCOPE_FLAG_VIPERRELOC) { + if (native_scope_flags & MP_SCOPE_FLAG_VIPERRELOC) { #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE // If native code needs relocations then it's not guaranteed that a pointer to // the head of `buf` (containing the machine code) will be retained for the GC @@ -560,55 +366,90 @@ STATIC mp_raw_code_t *load_raw_code(mp_reader_t *reader, qstr_window_t *qw) { } #endif + if (kind == MP_CODE_NATIVE_PY) { + #if !MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE + prelude_ptr = fun_data + prelude_offset; + #endif + if (n_children == 0) { + children = (void *)prelude_ptr; + } else { + children[n_children] = (void *)prelude_ptr; + } + } + // Assign native code to raw code object mp_emit_glue_assign_native(rc, kind, - fun_data, fun_data_len, const_table, + fun_data, fun_data_len, + children, #if MICROPY_PERSISTENT_CODE_SAVE + n_children, prelude_offset, - n_obj, n_raw_code, - n_qstr_link, NULL, #endif - prelude.n_pos_args, prelude.scope_flags, type_sig); + native_scope_flags, native_n_pos_args, native_type_sig + ); #endif } return rc; } -mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader) { +mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t *context) { byte header[4]; read_bytes(reader, header, sizeof(header)); if (header[0] != 'C' || header[1] != MPY_VERSION || MPY_FEATURE_DECODE_FLAGS(header[2]) != MPY_FEATURE_FLAGS - || header[3] > mp_small_int_bits() - || read_uint(reader, NULL) > QSTR_WINDOW_SIZE) { - mp_raise_ValueError(MP_ERROR_TEXT("Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info.")); + || header[3] > MP_SMALL_INT_BITS) { + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); } if (MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE) { byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); if (!MPY_FEATURE_ARCH_TEST(arch)) { - mp_raise_ValueError(MP_ERROR_TEXT("incompatible native .mpy architecture")); + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy arch")); } } - qstr_window_t qw; - qw.idx = 0; - mp_raw_code_t *rc = load_raw_code(reader, &qw); + + size_t n_qstr = read_uint(reader); + size_t n_obj = read_uint(reader); + mp_module_context_alloc_tables(context, n_qstr, n_obj); + + // Load qstrs. + for (size_t i = 0; i < n_qstr; ++i) { + context->constants.qstr_table[i] = load_qstr(reader); + } + + // Load constant objects. + for (size_t i = 0; i < n_obj; ++i) { + context->constants.obj_table[i] = load_obj(reader); + } + + // Load top-level module. + mp_compiled_module_t cm2; + cm2.rc = load_raw_code(reader, context); + cm2.context = context; + + #if MICROPY_PERSISTENT_CODE_SAVE + cm2.has_native = MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE; + cm2.n_qstr = n_qstr; + cm2.n_obj = n_obj; + #endif + reader->close(reader->data); - return rc; + + return cm2; } -mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len) { +mp_compiled_module_t mp_raw_code_load_mem(const byte *buf, size_t len, mp_module_context_t *context) { mp_reader_t reader; mp_reader_new_mem(&reader, buf, len, 0); - return mp_raw_code_load(&reader); + return mp_raw_code_load(&reader, context); } #if MICROPY_HAS_FILE_READER -mp_raw_code_t *mp_raw_code_load_file(const char *filename) { +mp_compiled_module_t mp_raw_code_load_file(const char *filename, mp_module_context_t *context) { mp_reader_t reader; mp_reader_new_file(&reader, filename); - return mp_raw_code_load(&reader); + return mp_raw_code_load(&reader, context); } #endif // MICROPY_HAS_FILE_READER @@ -635,54 +476,72 @@ STATIC void mp_print_uint(mp_print_t *print, size_t n) { print->print_strn(print->data, (char *)p, buf + sizeof(buf) - p); } -STATIC void save_qstr(mp_print_t *print, qstr_window_t *qw, qstr qst) { +STATIC void save_qstr(mp_print_t *print, qstr qst) { if (qst <= QSTR_LAST_STATIC) { // encode static qstr - byte buf[2] = {0, qst & 0xff}; - mp_print_bytes(print, buf, 2); - return; - } - size_t idx = qstr_window_insert(qw, qst); - if (idx < QSTR_WINDOW_SIZE) { - // qstr found in window, encode index to it - mp_print_uint(print, idx << 1 | 1); + mp_print_uint(print, qst << 1 | 1); return; } size_t len; const byte *str = qstr_data(qst, &len); mp_print_uint(print, len << 1); - mp_print_bytes(print, str, len); + mp_print_bytes(print, str, len + 1); // +1 to store null terminator } STATIC void save_obj(mp_print_t *print, mp_obj_t o) { + #if MICROPY_EMIT_MACHINE_CODE + if (o == MP_OBJ_FROM_PTR(&mp_fun_table)) { + byte obj_type = MP_PERSISTENT_OBJ_FUN_TABLE; + mp_print_bytes(print, &obj_type, 1); + } else + #endif if (mp_obj_is_str_or_bytes(o)) { byte obj_type; if (mp_obj_is_str(o)) { - obj_type = 's'; + obj_type = MP_PERSISTENT_OBJ_STR; } else { - obj_type = 'b'; + obj_type = MP_PERSISTENT_OBJ_BYTES; } size_t len; const char *str = mp_obj_str_get_data(o, &len); mp_print_bytes(print, &obj_type, 1); mp_print_uint(print, len); - mp_print_bytes(print, (const byte *)str, len); + mp_print_bytes(print, (const byte *)str, len + 1); // +1 to store null terminator + } else if (o == mp_const_none) { + byte obj_type = MP_PERSISTENT_OBJ_NONE; + mp_print_bytes(print, &obj_type, 1); + } else if (o == mp_const_false) { + byte obj_type = MP_PERSISTENT_OBJ_FALSE; + mp_print_bytes(print, &obj_type, 1); + } else if (o == mp_const_true) { + byte obj_type = MP_PERSISTENT_OBJ_TRUE; + mp_print_bytes(print, &obj_type, 1); } else if (MP_OBJ_TO_PTR(o) == &mp_const_ellipsis_obj) { - byte obj_type = 'e'; + byte obj_type = MP_PERSISTENT_OBJ_ELLIPSIS; + mp_print_bytes(print, &obj_type, 1); + } else if (mp_obj_is_type(o, &mp_type_tuple)) { + size_t len; + mp_obj_t *items; + mp_obj_tuple_get(o, &len, &items); + byte obj_type = MP_PERSISTENT_OBJ_TUPLE; mp_print_bytes(print, &obj_type, 1); + mp_print_uint(print, len); + for (size_t i = 0; i < len; ++i) { + save_obj(print, items[i]); + } } else { // we save numbers using a simplistic text representation // TODO could be improved byte obj_type; - if (mp_obj_is_type(o, &mp_type_int)) { - obj_type = 'i'; + if (mp_obj_is_int(o)) { + obj_type = MP_PERSISTENT_OBJ_INT; #if MICROPY_PY_BUILTINS_COMPLEX } else if (mp_obj_is_type(o, &mp_type_complex)) { - obj_type = 'c'; + obj_type = MP_PERSISTENT_OBJ_COMPLEX; #endif } else { assert(mp_obj_is_float(o)); - obj_type = 'f'; + obj_type = MP_PERSISTENT_OBJ_FLOAT; } vstr_t vstr; mp_print_t pr; @@ -695,142 +554,41 @@ STATIC void save_obj(mp_print_t *print, mp_obj_t o) { } } -STATIC void save_prelude_qstrs(mp_print_t *print, qstr_window_t *qw, const byte *ip) { - save_qstr(print, qw, ip[0] | (ip[1] << 8)); // simple_name - save_qstr(print, qw, ip[2] | (ip[3] << 8)); // source_file -} - -STATIC void save_bytecode(mp_print_t *print, qstr_window_t *qw, const byte *ip, const byte *ip_top) { - while (ip < ip_top) { - size_t sz; - uint f = mp_opcode_format(ip, &sz, true); - if (f == MP_BC_FORMAT_QSTR) { - mp_print_bytes(print, ip, 1); - qstr qst = ip[1] | (ip[2] << 8); - save_qstr(print, qw, qst); - ip += 3; - sz -= 3; - } - mp_print_bytes(print, ip, sz); - ip += sz; - } -} - -STATIC void save_raw_code(mp_print_t *print, mp_raw_code_t *rc, qstr_window_t *qstr_window) { +STATIC void save_raw_code(mp_print_t *print, const mp_raw_code_t *rc) { // Save function kind and data length - mp_print_uint(print, (rc->fun_data_len << 2) | (rc->kind - MP_CODE_BYTECODE)); - - bytecode_prelude_t prelude; - - if (rc->kind == MP_CODE_BYTECODE) { - // Extract prelude - const byte *ip = rc->fun_data; - const byte *ip_info = extract_prelude(&ip, &prelude); + mp_print_uint(print, (rc->fun_data_len << 3) | ((rc->n_children != 0) << 2) | (rc->kind - MP_CODE_BYTECODE)); - // Save prelude - mp_print_bytes(print, rc->fun_data, ip_info - (const byte *)rc->fun_data); - save_prelude_qstrs(print, qstr_window, ip_info); - ip_info += 4; - mp_print_bytes(print, ip_info, ip - ip_info); + // Save function code. + mp_print_bytes(print, rc->fun_data, rc->fun_data_len); - // Save bytecode - const byte *ip_top = (const byte *)rc->fun_data + rc->fun_data_len; - save_bytecode(print, qstr_window, ip, ip_top); #if MICROPY_EMIT_MACHINE_CODE - } else { - // Save native code - mp_print_bytes(print, rc->fun_data, rc->fun_data_len); - - if (rc->kind == MP_CODE_NATIVE_PY || rc->kind == MP_CODE_NATIVE_VIPER) { - // Save qstr link table for native code - mp_print_uint(print, rc->n_qstr); - for (size_t i = 0; i < rc->n_qstr; ++i) { - mp_print_uint(print, rc->qstr_link[i].off); - save_qstr(print, qstr_window, rc->qstr_link[i].qst); - } + if (rc->kind == MP_CODE_NATIVE_PY) { + // Save prelude size + mp_print_uint(print, rc->prelude_offset); + } else if (rc->kind == MP_CODE_NATIVE_VIPER || rc->kind == MP_CODE_NATIVE_ASM) { + // Save basic scope info for viper and asm + mp_print_uint(print, rc->scope_flags & MP_SCOPE_FLAG_ALL_SIG); + if (rc->kind == MP_CODE_NATIVE_ASM) { + mp_print_uint(print, rc->n_pos_args); + mp_print_uint(print, rc->type_sig); } - - if (rc->kind == MP_CODE_NATIVE_PY) { - // Save prelude size - mp_print_uint(print, rc->prelude_offset); - - // Extract prelude and save qstrs in prelude - const byte *ip = (const byte *)rc->fun_data + rc->prelude_offset; - const byte *ip_info = extract_prelude(&ip, &prelude); - save_prelude_qstrs(print, qstr_window, ip_info); - } else { - // Save basic scope info for viper and asm - mp_print_uint(print, rc->scope_flags & MP_SCOPE_FLAG_ALL_SIG); - prelude.n_pos_args = 0; - prelude.n_kwonly_args = 0; - if (rc->kind == MP_CODE_NATIVE_ASM) { - mp_print_uint(print, rc->n_pos_args); - mp_print_uint(print, rc->type_sig); - } - } - #endif } + #endif - if (rc->kind != MP_CODE_NATIVE_ASM) { - // Save constant table for bytecode, native and viper - - // Number of entries in constant table - mp_print_uint(print, rc->n_obj); - mp_print_uint(print, rc->n_raw_code); - - const mp_uint_t *const_table = rc->const_table; - - // Save function argument names (initial entries in const_table) - // (viper has n_pos_args=n_kwonly_args=0 so doesn't save any qstrs here) - for (size_t i = 0; i < prelude.n_pos_args + prelude.n_kwonly_args; ++i) { - mp_obj_t o = (mp_obj_t)*const_table++; - save_qstr(print, qstr_window, MP_OBJ_QSTR_VALUE(o)); - } - - if (rc->kind != MP_CODE_BYTECODE) { - // Skip saving mp_fun_table entry - ++const_table; - } - - // Save constant objects and raw code children - for (size_t i = 0; i < rc->n_obj; ++i) { - save_obj(print, (mp_obj_t)*const_table++); - } - for (size_t i = 0; i < rc->n_raw_code; ++i) { - save_raw_code(print, (mp_raw_code_t *)(uintptr_t)*const_table++, qstr_window); - } - } -} - -STATIC bool mp_raw_code_has_native(mp_raw_code_t *rc) { - if (rc->kind != MP_CODE_BYTECODE) { - return true; - } - - const byte *ip = rc->fun_data; - bytecode_prelude_t prelude; - extract_prelude(&ip, &prelude); - - const mp_uint_t *const_table = rc->const_table - + prelude.n_pos_args + prelude.n_kwonly_args - + rc->n_obj; - - for (size_t i = 0; i < rc->n_raw_code; ++i) { - if (mp_raw_code_has_native((mp_raw_code_t *)(uintptr_t)*const_table++)) { - return true; + if (rc->n_children) { + mp_print_uint(print, rc->n_children); + for (size_t i = 0; i < rc->n_children; ++i) { + save_raw_code(print, rc->children[i]); } } - - return false; } -void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print) { +void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print) { // header contains: // byte 'C' // byte version // byte feature flags // byte number of bits in a small int - // uint size of qstr window byte header[4] = { 'C', MPY_VERSION, @@ -838,19 +596,30 @@ void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print) { #if MICROPY_DYNAMIC_COMPILER mp_dynamic_compiler.small_int_bits, #else - mp_small_int_bits(), + MP_SMALL_INT_BITS, #endif }; - if (mp_raw_code_has_native(rc)) { + if (cm->has_native) { header[2] |= MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH_DYNAMIC); } mp_print_bytes(print, header, sizeof(header)); - mp_print_uint(print, QSTR_WINDOW_SIZE); - qstr_window_t qw; - qw.idx = 0; - memset(qw.window, 0, sizeof(qw.window)); - save_raw_code(print, rc, &qw); + // Number of entries in constant table. + mp_print_uint(print, cm->n_qstr); + mp_print_uint(print, cm->n_obj); + + // Save qstrs. + for (size_t i = 0; i < cm->n_qstr; ++i) { + save_qstr(print, cm->context->constants.qstr_table[i]); + } + + // Save constant objects. + for (size_t i = 0; i < cm->n_obj; ++i) { + save_obj(print, (mp_obj_t)cm->context->constants.obj_table[i]); + } + + // Save outer raw code, which will save all its child raw codes. + save_raw_code(print, cm->rc); } #if MICROPY_PERSISTENT_CODE_SAVE_FILE @@ -867,12 +636,12 @@ STATIC void fd_print_strn(void *env, const char *str, size_t len) { (void)ret; } -void mp_raw_code_save_file(mp_raw_code_t *rc, const char *filename) { +void mp_raw_code_save_file(mp_compiled_module_t *cm, const char *filename) { MP_THREAD_GIL_EXIT(); int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); MP_THREAD_GIL_ENTER(); mp_print_t fd_print = {(void *)(intptr_t)fd, fd_print_strn}; - mp_raw_code_save(rc, &fd_print); + mp_raw_code_save(cm, &fd_print); MP_THREAD_GIL_EXIT(); close(fd); MP_THREAD_GIL_ENTER(); diff --git a/py/persistentcode.h b/py/persistentcode.h index 1c53ca12cf25d..7ba86c1eb71da 100644 --- a/py/persistentcode.h +++ b/py/persistentcode.h @@ -31,7 +31,7 @@ #include "py/emitglue.h" // The current version of .mpy files -#define MPY_VERSION 5 +#define MPY_VERSION 6 // Macros to encode/decode flags to/from the feature byte #define MPY_FEATURE_ENCODE_FLAGS(flags) (flags) @@ -42,15 +42,11 @@ #define MPY_FEATURE_DECODE_ARCH(feat) ((feat) >> 2) // The feature flag bits encode the compile-time config options that affect -// the generate bytecode. Note: position 0 is now unused -// (formerly MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE). -#define MPY_FEATURE_FLAGS ( \ - ((MICROPY_PY_BUILTINS_STR_UNICODE) << 1) \ - ) +// the generate bytecode. Note: no longer used. +// (formerly MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE and MICROPY_PY_BUILTINS_STR_UNICODE). +#define MPY_FEATURE_FLAGS (0) // This is a version of the flags that can be configured at runtime. -#define MPY_FEATURE_FLAGS_DYNAMIC ( \ - ((MICROPY_PY_BUILTINS_STR_UNICODE_DYNAMIC) << 1) \ - ) +#define MPY_FEATURE_FLAGS_DYNAMIC (0) // Define the host architecture #if MICROPY_EMIT_X86 @@ -67,7 +63,7 @@ #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV7EM) #endif #else - #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV7M) + #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_ARMV6M) #endif #define MPY_FEATURE_ARCH_TEST(x) (MP_NATIVE_ARCH_ARMV6M <= (x) && (x) <= MPY_FEATURE_ARCH) #elif MICROPY_EMIT_ARM @@ -102,12 +98,26 @@ enum { MP_NATIVE_ARCH_XTENSAWIN, }; -mp_raw_code_t *mp_raw_code_load(mp_reader_t *reader); -mp_raw_code_t *mp_raw_code_load_mem(const byte *buf, size_t len); -mp_raw_code_t *mp_raw_code_load_file(const char *filename); +enum { + MP_PERSISTENT_OBJ_FUN_TABLE = 0, + MP_PERSISTENT_OBJ_NONE, + MP_PERSISTENT_OBJ_FALSE, + MP_PERSISTENT_OBJ_TRUE, + MP_PERSISTENT_OBJ_ELLIPSIS, + MP_PERSISTENT_OBJ_STR, + MP_PERSISTENT_OBJ_BYTES, + MP_PERSISTENT_OBJ_INT, + MP_PERSISTENT_OBJ_FLOAT, + MP_PERSISTENT_OBJ_COMPLEX, + MP_PERSISTENT_OBJ_TUPLE, +}; + +mp_compiled_module_t mp_raw_code_load(mp_reader_t *reader, mp_module_context_t *ctx); +mp_compiled_module_t mp_raw_code_load_mem(const byte *buf, size_t len, mp_module_context_t *ctx); +mp_compiled_module_t mp_raw_code_load_file(const char *filename, mp_module_context_t *ctx); -void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print); -void mp_raw_code_save_file(mp_raw_code_t *rc, const char *filename); +void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print); +void mp_raw_code_save_file(mp_compiled_module_t *cm, const char *filename); void mp_native_relocate(void *reloc, uint8_t *text, uintptr_t reloc_text); diff --git a/py/profile.c b/py/profile.c index 81c80f1168978..4e23e9eac43b5 100644 --- a/py/profile.c +++ b/py/profile.c @@ -27,14 +27,16 @@ #include "py/profile.h" #include "py/bc0.h" #include "py/gc.h" +#include "py/objfun.h" #if MICROPY_PY_SYS_SETTRACE #define prof_trace_cb MP_STATE_THREAD(prof_trace_callback) +#define QSTR_MAP(context, idx) (context->constants.qstr_table[idx]) STATIC uint mp_prof_bytecode_lineno(const mp_raw_code_t *rc, size_t bc) { const mp_bytecode_prelude_t *prelude = &rc->prelude; - return mp_bytecode_get_source_line(prelude->line_info, bc); + return mp_bytecode_get_source_line(prelude->line_info, prelude->line_info_top, bc); } void mp_prof_extract_prelude(const byte *bytecode, mp_bytecode_prelude_t *prelude) { @@ -50,13 +52,14 @@ void mp_prof_extract_prelude(const byte *bytecode, mp_bytecode_prelude_t *prelud MP_BC_PRELUDE_SIZE_DECODE(ip); - prelude->line_info = ip + 4; + prelude->line_info_top = ip + n_info; prelude->opcodes = ip + n_info + n_cell; - qstr block_name = ip[0] | (ip[1] << 8); - qstr source_file = ip[2] | (ip[3] << 8); - prelude->qstr_block_name = block_name; - prelude->qstr_source_file = source_file; + prelude->qstr_block_name_idx = mp_decode_uint_value(ip); + for (size_t i = 0; i < 1 + n_pos_args + n_kwonly_args; ++i) { + ip = mp_decode_uint_skip(ip); + } + prelude->line_info = ip; } /******************************************************************************/ @@ -68,23 +71,20 @@ STATIC void code_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t k const mp_raw_code_t *rc = o->rc; const mp_bytecode_prelude_t *prelude = &rc->prelude; mp_printf(print, - "", - prelude->qstr_block_name, + "", + QSTR_MAP(o->context, prelude->qstr_block_name_idx), o, - prelude->qstr_source_file, + QSTR_MAP(o->context, 0), rc->line_of_definition ); } -STATIC mp_obj_tuple_t *code_consts(const mp_raw_code_t *rc) { - const mp_bytecode_prelude_t *prelude = &rc->prelude; - int start = prelude->n_pos_args + prelude->n_kwonly_args + rc->n_obj; - int stop = prelude->n_pos_args + prelude->n_kwonly_args + rc->n_obj + rc->n_raw_code; - mp_obj_tuple_t *consts = MP_OBJ_TO_PTR(mp_obj_new_tuple(stop - start + 1, NULL)); +STATIC mp_obj_tuple_t *code_consts(const mp_module_context_t *context, const mp_raw_code_t *rc) { + mp_obj_tuple_t *consts = MP_OBJ_TO_PTR(mp_obj_new_tuple(rc->n_children + 1, NULL)); size_t const_no = 0; - for (int i = start; i < stop; ++i) { - mp_obj_t code = mp_obj_new_code((const mp_raw_code_t *)MP_OBJ_TO_PTR(rc->const_table[i])); + for (size_t i = 0; i < rc->n_children; ++i) { + mp_obj_t code = mp_obj_new_code(context, rc->children[i]); if (code == MP_OBJ_NULL) { m_malloc_fail(sizeof(mp_obj_code_t)); } @@ -149,16 +149,16 @@ STATIC void code_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { ); break; case MP_QSTR_co_consts: - dest[0] = MP_OBJ_FROM_PTR(code_consts(rc)); + dest[0] = MP_OBJ_FROM_PTR(code_consts(o->context, rc)); break; case MP_QSTR_co_filename: - dest[0] = MP_OBJ_NEW_QSTR(prelude->qstr_source_file); + dest[0] = MP_OBJ_NEW_QSTR(QSTR_MAP(o->context, 0)); break; case MP_QSTR_co_firstlineno: dest[0] = MP_OBJ_NEW_SMALL_INT(mp_prof_bytecode_lineno(rc, 0)); break; case MP_QSTR_co_name: - dest[0] = MP_OBJ_NEW_QSTR(prelude->qstr_block_name); + dest[0] = MP_OBJ_NEW_QSTR(QSTR_MAP(o->context, prelude->qstr_block_name_idx)); break; case MP_QSTR_co_names: dest[0] = MP_OBJ_FROM_PTR(o->dict_locals); @@ -180,12 +180,13 @@ const mp_obj_type_t mp_type_settrace_codeobj = { .attr = code_attr, }; -mp_obj_t mp_obj_new_code(const mp_raw_code_t *rc) { +mp_obj_t mp_obj_new_code(const mp_module_context_t *context, const mp_raw_code_t *rc) { mp_obj_code_t *o = m_new_obj_maybe(mp_obj_code_t); if (o == NULL) { return MP_OBJ_NULL; } o->base.type = &mp_type_settrace_codeobj; + o->context = context; o->rc = rc; o->dict_locals = mp_locals_get(); // this is a wrong! how to do this properly? o->lnotab = MP_OBJ_NULL; @@ -202,11 +203,11 @@ STATIC void frame_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t const mp_raw_code_t *rc = code->rc; const mp_bytecode_prelude_t *prelude = &rc->prelude; mp_printf(print, - "", + "", frame, - prelude->qstr_source_file, + QSTR_MAP(code->context, 0), frame->lineno, - prelude->qstr_block_name + QSTR_MAP(code->context, prelude->qstr_block_name_idx) ); } @@ -229,7 +230,7 @@ STATIC void frame_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { dest[0] = MP_OBJ_FROM_PTR(o->code); break; case MP_QSTR_f_globals: - dest[0] = MP_OBJ_FROM_PTR(o->code_state->fun_bc->globals); + dest[0] = MP_OBJ_FROM_PTR(o->code_state->fun_bc->context->module.globals); break; case MP_QSTR_f_lasti: dest[0] = MP_OBJ_NEW_SMALL_INT(o->lasti); @@ -258,7 +259,7 @@ mp_obj_t mp_obj_new_frame(const mp_code_state_t *code_state) { return MP_OBJ_NULL; } - mp_obj_code_t *code = o->code = MP_OBJ_TO_PTR(mp_obj_new_code(code_state->fun_bc->rc)); + mp_obj_code_t *code = o->code = MP_OBJ_TO_PTR(mp_obj_new_code(code_state->fun_bc->context, code_state->fun_bc->rc)); if (code == NULL) { return MP_OBJ_NULL; } @@ -938,7 +939,7 @@ void mp_prof_print_instr(const byte *ip, mp_code_state_t *code_state) { /* long path */ if (1) { mp_printf(&mp_plat_print, - "@%p:%q:%q+0x%04x:%d", + "@0x%p:%q:%q+0x%04x:%d", ip, prelude->qstr_source_file, prelude->qstr_block_name, diff --git a/py/profile.h b/py/profile.h index 64e207d04fbf3..7f3f914034623 100644 --- a/py/profile.h +++ b/py/profile.h @@ -34,7 +34,9 @@ #define mp_prof_is_executing MP_STATE_THREAD(prof_callback_is_executing) typedef struct _mp_obj_code_t { + // TODO this was 4 words mp_obj_base_t base; + const mp_module_context_t *context; const mp_raw_code_t *rc; mp_obj_dict_t *dict_locals; mp_obj_t lnotab; @@ -53,7 +55,7 @@ typedef struct _mp_obj_frame_t { void mp_prof_extract_prelude(const byte *bytecode, mp_bytecode_prelude_t *prelude); -mp_obj_t mp_obj_new_code(const mp_raw_code_t *rc); +mp_obj_t mp_obj_new_code(const mp_module_context_t *mc, const mp_raw_code_t *rc); mp_obj_t mp_obj_new_frame(const mp_code_state_t *code_state); // This is the implementation for the sys.settrace diff --git a/py/py.mk b/py/py.mk index 4a2d8544f11a3..81da81ba0f974 100644 --- a/py/py.mk +++ b/py/py.mk @@ -75,7 +75,6 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ nlrsetjmp.o \ malloc.o \ gc.o \ - gc_long_lived.o \ pystack.o \ qstr.o \ vstr.o \ @@ -192,6 +191,7 @@ PY_EXTMOD_O_BASENAME = \ extmod/moduasyncio.o \ extmod/moductypes.o \ extmod/modujson.o \ + extmod/moduos.o \ extmod/modure.o \ extmod/moduzlib.o \ extmod/moduheapq.o \ @@ -200,7 +200,6 @@ PY_EXTMOD_O_BASENAME = \ extmod/modubinascii.o \ extmod/modurandom.o \ extmod/moduselect.o \ - extmod/modframebuf.o \ extmod/vfs.o \ extmod/vfs_blockdev.o \ extmod/vfs_reader.o \ @@ -228,10 +227,7 @@ endif # Sources that may contain qstrings SRC_QSTR_IGNORE = py/nlr% -SRC_QSTR_EMITNATIVE = py/emitn% SRC_QSTR += $(SRC_MOD) $(filter-out $(SRC_QSTR_IGNORE),$(PY_CORE_O_BASENAME:.o=.c)) $(PY_EXTMOD_O_BASENAME:.o=.c) -# Sources that only hold QSTRs after pre-processing. -SRC_QSTR_PREPROCESSOR = $(addprefix $(TOP)/, $(filter $(SRC_QSTR_EMITNATIVE),$(PY_CORE_O_BASENAME:.o=.c))) # Anything that depends on FORCE will be considered out-of-date FORCE: @@ -245,45 +241,44 @@ $(HEADER_BUILD)/mpversion.h: FORCE | $(HEADER_BUILD) # overall config, so they need to be caught MPCONFIGPORT_MK = $(wildcard mpconfigport.mk) -$(HEADER_BUILD)/$(TRANSLATION).mo: $(TOP)/locale/$(TRANSLATION).po | $(HEADER_BUILD) - $(Q)$(PYTHON) $(TOP)/tools/msgfmt.py -o $@ $^ - -$(HEADER_BUILD)/qstrdefs.preprocessed.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) - $(STEPECHO) "GEN $@" - $(Q)cat $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) | $(SED) 's/^Q(.*)/"&"/' | $(CPP) $(CFLAGS) - | $(SED) 's/^"\(Q(.*)\)"/\1/' > $@ - # qstr data -$(HEADER_BUILD)/qstrdefs.enum.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h - $(STEPECHO) "GEN $@" - $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py --output_type=enums $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ - # Adding an order only dependency on $(HEADER_BUILD) causes $(HEADER_BUILD) to get # created before we run the script to generate the .h # Note: we need to protect the qstr names from the preprocessor, so we wrap # the lines in "" and then unwrap after the preprocessor is finished. -$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h - $(STEPECHO) "GEN $@" - $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py --output_type=data $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ +# See more information about this process in docs/develop/qstr.rst. +$(HEADER_BUILD)/qstrdefs.generated.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) $(PY_SRC)/makeqstrdata.py mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) + $(ECHO) "GEN $@" + $(Q)$(CAT) $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) | $(SED) 's/^Q(.*)/"&"/' | $(CPP) $(CFLAGS) - | $(SED) 's/^\"\(Q(.*)\)\"/\1/' > $(HEADER_BUILD)/qstrdefs.preprocessed.h + $(Q)$(PYTHON) $(PY_SRC)/makeqstrdata.py $(HEADER_BUILD)/qstrdefs.preprocessed.h > $@ + +$(HEADER_BUILD)/compressed.data.h: $(HEADER_BUILD)/compressed.collected + $(ECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makecompresseddata.py $< > $@ + +// CIRCUITPY: for translations +$(HEADER_BUILD)/$(TRANSLATION).mo: $(TOP)/locale/$(TRANSLATION).po | $(HEADER_BUILD) + $(Q)$(PYTHON) $(TOP)/tools/msgfmt.py -o $@ $^ -# Is generated as a side-effect of building compression.generated.h +# translations-*.c is generated as a side-effect of building compressed_translations.generated.h # Specifying both in a single rule actually causes the rule to be run twice! # This alternative makes it run just once. -$(PY_BUILD)/translations-$(TRANSLATION).c: $(HEADER_BUILD)/compression.generated.h +# Another alternative is "grouped targets" (`a b &: c`), available in GNU make 4.3 and later. +# TODO: use grouped targets when we expect GNU make >= 4.3 is pervasive. +$(PY_BUILD)/translations-$(TRANSLATION).c: $(HEADER_BUILD)/compressed_translations.generated.h @true -$(HEADER_BUILD)/compression.generated.h: $(PY_SRC)/maketranslationdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.preprocessed.h +$(HEADER_BUILD)/compressed_translations.generated.h: $(PY_SRC)/maketranslationdata.py $(HEADER_BUILD)/$(TRANSLATION).mo $(HEADER_BUILD)/qstrdefs.generated.h $(STEPECHO) "GEN $@" $(Q)mkdir -p $(PY_BUILD) - $(Q)$(PYTHON) $(PY_SRC)/maketranslationdata.py --compression_filename $(HEADER_BUILD)/compression.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo --translation_filename $(PY_BUILD)/translations-$(TRANSLATION).c $(HEADER_BUILD)/qstrdefs.preprocessed.h + $(Q)$(PYTHON) $(PY_SRC)/maketranslationdata.py --compression_filename $(HEADER_BUILD)/compressed_translations.generated.h --translation $(HEADER_BUILD)/$(TRANSLATION).mo --translation_filename $(PY_BUILD)/translations-$(TRANSLATION).c $(HEADER_BUILD)/qstrdefs.preprocessed.h PY_CORE_O += $(PY_BUILD)/translations-$(TRANSLATION).o -$(PY_BUILD)/qstr.o: $(HEADER_BUILD)/qstrdefs.generated.h - # build a list of registered modules for py/objmodule.c. -$(HEADER_BUILD)/moduledefs.h: $(SRC_QSTR) $(QSTR_GLOBAL_DEPENDENCIES) | $(HEADER_BUILD)/mpversion.h - @$(ECHO) "GEN $@" - $(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py --vpath="., $(TOP), $(USER_C_MODULES)" $(SRC_QSTR) > $@ +$(HEADER_BUILD)/moduledefs.h: $(HEADER_BUILD)/moduledefs.collected + @$(STEPECHO) "GEN $@" + $(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py $< > $@ # Standard C functions like memset need to be compiled with special flags so # the compiler does not optimise these functions in terms of themselves. @@ -294,6 +289,7 @@ $(BUILD)/shared/libc/string0.o: CFLAGS += $(CFLAGS_BUILTIN) # that the function preludes are of a minimal and predictable form. $(PY_BUILD)/nlr%.o: CFLAGS += -Os +# CIRCUITPY: separate SUPEROPT for gc.o and vm.o # optimising gc for speed; 5ms down to 4ms on pybv2 ifndef SUPEROPT_GC SUPEROPT_GC = 1 diff --git a/py/pystack.c b/py/pystack.c index 696b033377c0b..409ca11a7ffe6 100644 --- a/py/pystack.c +++ b/py/pystack.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George + * Copyright (c) 2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/pystack.h b/py/pystack.h index 169d58b6f7787..4bb717c4822c6 100644 --- a/py/pystack.h +++ b/py/pystack.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2017 Damien P. George + * Copyright (c) 2017 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/qstr.c b/py/qstr.c index 09ef9ea7ed6d8..5ff8b3bd54bbc 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,6 @@ #include #include -#include "py/gc.h" #include "py/mpstate.h" #include "py/qstr.h" #include "py/gc.h" @@ -77,29 +76,34 @@ mp_uint_t qstr_compute_hash(const byte *data, size_t len) { } return hash; } -#ifndef CIRCUITPY_PRECOMPUTE_QSTR_ATTR -#define CIRCUITPY_PRECOMPUTE_QSTR_ATTR (1) -#endif -#if CIRCUITPY_PRECOMPUTE_QSTR_ATTR == 1 -const qstr_attr_t mp_qstr_const_attr[MP_QSTRnumber_of] = { + +const qstr_hash_t mp_qstr_const_hashes[] = { #ifndef NO_QSTR -#define QDEF(id, hash, len, str) { hash, len }, +#define QDEF(id, hash, len, str) hash, +#define TRANSLATION(id, length, compressed ...) + #include "genhdr/qstrdefs.generated.h" +#undef TRANSLATION +#undef QDEF + #endif +}; + +const qstr_len_t mp_qstr_const_lengths[] = { + #ifndef NO_QSTR +#define QDEF(id, hash, len, str) len, #define TRANSLATION(id, length, compressed ...) #include "genhdr/qstrdefs.generated.h" #undef TRANSLATION #undef QDEF #endif }; -#else -qstr_attr_t mp_qstr_const_attr[MP_QSTRnumber_of]; -#endif const qstr_pool_t mp_qstr_const_pool = { NULL, // no previous pool 0, // no previous pool MICROPY_ALLOC_QSTR_ENTRIES_INIT, MP_QSTRnumber_of, // corresponds to number of strings in array just below - (qstr_attr_t *)mp_qstr_const_attr, + (qstr_hash_t *)mp_qstr_const_hashes, + (qstr_len_t *)mp_qstr_const_lengths, { #ifndef NO_QSTR #define QDEF(id, hash, len, str) str, @@ -122,32 +126,21 @@ void qstr_init(void) { MP_STATE_VM(last_pool) = (qstr_pool_t *)&CONST_POOL; // we won't modify the const_pool since it has no allocated room left MP_STATE_VM(qstr_last_chunk) = NULL; - #if CIRCUITPY_PRECOMPUTE_QSTR_ATTR == 0 - if (mp_qstr_const_attr[MP_QSTR_circuitpython].len == 0) { - for (size_t i = 0; i < mp_qstr_const_pool.len; i++) { - size_t len = strlen(mp_qstr_const_pool.qstrs[i]); - mp_qstr_const_attr[i].hash = qstr_compute_hash((const byte *)mp_qstr_const_pool.qstrs[i], len); - mp_qstr_const_attr[i].len = len; - } - } - #endif - #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL mp_thread_mutex_init(&MP_STATE_VM(qstr_mutex)); #endif } -STATIC const char *PLACE_IN_ITCM(find_qstr)(qstr q, qstr_attr_t *attr) { +STATIC const qstr_pool_t *PLACE_IN_ITCM(find_qstr)(qstr *q) { // search pool for this qstr // total_prev_len==0 in the final pool, so the loop will always terminate const qstr_pool_t *pool = MP_STATE_VM(last_pool); - while (q < pool->total_prev_len) { + while (*q < pool->total_prev_len) { pool = pool->prev; } - q -= pool->total_prev_len; - assert(q < pool->len); - *attr = pool->attrs[q]; - return pool->qstrs[q]; + *q -= pool->total_prev_len; + assert(*q < pool->len); + return pool; } // qstr_mutex must be taken while in this function @@ -156,19 +149,14 @@ STATIC qstr qstr_add(mp_uint_t hash, mp_uint_t len, const char *q_ptr) { // make sure we have room in the pool for a new qstr if (MP_STATE_VM(last_pool)->len >= MP_STATE_VM(last_pool)->alloc) { - uint32_t new_pool_length = MP_STATE_VM(last_pool)->alloc * 2; - if (new_pool_length > MICROPY_QSTR_POOL_MAX_ENTRIES) { - new_pool_length = MICROPY_QSTR_POOL_MAX_ENTRIES; - } + size_t new_alloc = MP_STATE_VM(last_pool)->alloc * 2; #ifdef MICROPY_QSTR_EXTRA_POOL // Put a lower bound on the allocation size in case the extra qstr pool has few entries - if (new_pool_length < MICROPY_ALLOC_QSTR_ENTRIES_INIT) { - new_pool_length = MICROPY_ALLOC_QSTR_ENTRIES_INIT; - } + new_alloc = MAX(MICROPY_ALLOC_QSTR_ENTRIES_INIT, new_alloc); #endif mp_uint_t pool_size = sizeof(qstr_pool_t) - + (sizeof(const char *) + sizeof(qstr_attr_t)) * new_pool_length; - qstr_pool_t *pool = (qstr_pool_t *)m_malloc_maybe(pool_size, true); + + (sizeof(const char *) + sizeof(qstr_hash_t) + sizeof(qstr_len_t)) * new_alloc; + qstr_pool_t *pool = (qstr_pool_t *)m_malloc_maybe(pool_size); if (pool == NULL) { // Keep qstr_last_chunk consistent with qstr_pool_t: qstr_last_chunk is not scanned // at garbage collection since it's reachable from a qstr_pool_t. And the caller of @@ -177,12 +165,13 @@ STATIC qstr qstr_add(mp_uint_t hash, mp_uint_t len, const char *q_ptr) { // NULL'd. Otherwise it may become a dangling pointer at the next garbage collection. MP_STATE_VM(qstr_last_chunk) = NULL; QSTR_EXIT(); - m_malloc_fail(new_pool_length); + m_malloc_fail(new_alloc); } - pool->attrs = (qstr_attr_t *)(pool->qstrs + new_pool_length); + pool->hashes = (qstr_hash_t *)(pool->qstrs + new_alloc); + pool->lengths = (qstr_len_t *)(pool->hashes + new_alloc); pool->prev = MP_STATE_VM(last_pool); pool->total_prev_len = MP_STATE_VM(last_pool)->total_prev_len + MP_STATE_VM(last_pool)->len; - pool->alloc = new_pool_length; + pool->alloc = new_alloc; pool->len = 0; MP_STATE_VM(last_pool) = pool; DEBUG_printf("QSTR: allocate new pool of size %d\n", MP_STATE_VM(last_pool)->alloc); @@ -190,8 +179,8 @@ STATIC qstr qstr_add(mp_uint_t hash, mp_uint_t len, const char *q_ptr) { // add the new qstr mp_uint_t at = MP_STATE_VM(last_pool)->len; - MP_STATE_VM(last_pool)->attrs[at].hash = hash; - MP_STATE_VM(last_pool)->attrs[at].len = len; + MP_STATE_VM(last_pool)->hashes[at] = hash; + MP_STATE_VM(last_pool)->lengths[at] = len; MP_STATE_VM(last_pool)->qstrs[at] = q_ptr; MP_STATE_VM(last_pool)->len++; @@ -205,9 +194,9 @@ qstr qstr_find_strn(const char *str, size_t str_len) { // search pools for the data for (const qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL; pool = pool->prev) { - qstr_attr_t *attrs = pool->attrs; for (mp_uint_t at = 0, top = pool->len; at < top; at++) { - if (attrs[at].hash == str_hash && attrs[at].len == str_len && memcmp(pool->qstrs[at], str, str_len) == 0) { + if (pool->hashes[at] == str_hash && pool->lengths[at] == str_len + && memcmp(pool->qstrs[at], str, str_len) == 0) { return pool->total_prev_len + at; } } @@ -255,10 +244,10 @@ qstr qstr_from_strn(const char *str, size_t len) { if (al < MICROPY_ALLOC_QSTR_CHUNK_INIT) { al = MICROPY_ALLOC_QSTR_CHUNK_INIT; } - MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(char, al); + MP_STATE_VM(qstr_last_chunk) = m_new_maybe(char, al); if (MP_STATE_VM(qstr_last_chunk) == NULL) { // failed to allocate a large chunk so try with exact size - MP_STATE_VM(qstr_last_chunk) = m_new_ll_maybe(char, n_bytes); + MP_STATE_VM(qstr_last_chunk) = m_new_maybe(char, n_bytes); if (MP_STATE_VM(qstr_last_chunk) == NULL) { QSTR_EXIT(); m_malloc_fail(n_bytes); @@ -283,28 +272,25 @@ qstr qstr_from_strn(const char *str, size_t len) { return q; } -mp_uint_t PLACE_IN_ITCM(qstr_hash)(qstr q) { - qstr_attr_t attr; - find_qstr(q, &attr); - return attr.hash; +mp_uint_t qstr_hash(qstr q) { + const qstr_pool_t *pool = find_qstr(&q); + return pool->hashes[q]; } -size_t PLACE_IN_ITCM(qstr_len)(qstr q) { - qstr_attr_t attr; - find_qstr(q, &attr); - return attr.len; +size_t qstr_len(qstr q) { + const qstr_pool_t *pool = find_qstr(&q); + return pool->lengths[q]; } -const char *PLACE_IN_ITCM(qstr_str)(qstr q) { - qstr_attr_t attr; - return find_qstr(q, &attr); +const char *qstr_str(qstr q) { + const qstr_pool_t *pool = find_qstr(&q); + return pool->qstrs[q]; } -const byte *PLACE_IN_ITCM(qstr_data)(qstr q, size_t *len) { - qstr_attr_t attr; - const char *qd = find_qstr(q, &attr); - *len = attr.len; - return (byte *)qd; +const byte *qstr_data(qstr q, size_t *len) { + const qstr_pool_t *pool = find_qstr(&q); + *len = pool->lengths[q]; + return (byte *)pool->qstrs[q]; } void qstr_pool_info(size_t *n_pool, size_t *n_qstr, size_t *n_str_data_bytes, size_t *n_total_bytes) { @@ -316,14 +302,14 @@ void qstr_pool_info(size_t *n_pool, size_t *n_qstr, size_t *n_str_data_bytes, si for (const qstr_pool_t *pool = MP_STATE_VM(last_pool); pool != NULL && pool != &CONST_POOL; pool = pool->prev) { *n_pool += 1; *n_qstr += pool->len; - for (const qstr_attr_t *q = pool->attrs, *q_top = pool->attrs + pool->len; q < q_top; q++) { - *n_str_data_bytes += sizeof(*q) + q->len + 1; + for (qstr_len_t *l = pool->lengths, *l_top = pool->lengths + pool->len; l < l_top; l++) { + *n_str_data_bytes += *l + 1; } #if MICROPY_ENABLE_GC - // this counts actual bytes used in heap - *n_total_bytes += gc_nbytes(pool) - sizeof(qstr_attr_t) * pool->alloc; + *n_total_bytes += gc_nbytes(pool); // this counts actual bytes used in heap #else - *n_total_bytes += sizeof(qstr_pool_t) + sizeof(const char *) * pool->alloc; + *n_total_bytes += sizeof(qstr_pool_t) + + (sizeof(const char *) + sizeof(qstr_hash_t) + sizeof(qstr_len_t)) * pool->alloc; #endif } *n_total_bytes += *n_str_data_bytes; @@ -341,3 +327,78 @@ void qstr_dump_data(void) { QSTR_EXIT(); } #endif + +#if MICROPY_ROM_TEXT_COMPRESSION + +#ifdef NO_QSTR + +// If NO_QSTR is set, it means we're doing QSTR extraction. +// So we won't yet have "genhdr/compressed.data.h" + +#else + +// Emit the compressed_string_data string. +#define MP_COMPRESSED_DATA(x) STATIC const char *compressed_string_data = x; +#define MP_MATCH_COMPRESSED(a, b) +#include "genhdr/compressed.data.h" +#undef MP_COMPRESSED_DATA +#undef MP_MATCH_COMPRESSED + +#endif // NO_QSTR + +// This implements the "common word" compression scheme (see makecompresseddata.py) where the most +// common 128 words in error messages are replaced by their index into the list of common words. + +// The compressed string data is delimited by setting high bit in the final char of each word. +// e.g. aaaa<0x80|a>bbbbbb<0x80|b>.... +// This method finds the n'th string. +STATIC const byte *find_uncompressed_string(uint8_t n) { + const byte *c = (byte *)compressed_string_data; + while (n > 0) { + while ((*c & 0x80) == 0) { + ++c; + } + ++c; + --n; + } + return c; +} + +// Given a compressed string in src, decompresses it into dst. +// dst must be large enough (use MP_MAX_UNCOMPRESSED_TEXT_LEN+1). +void mp_decompress_rom_string(byte *dst, const mp_rom_error_text_t src_chr) { + // Skip past the 0xff marker. + const byte *src = (byte *)src_chr + 1; + // Need to add spaces around compressed words, except for the first (i.e. transition from 1<->2). + // 0 = start, 1 = compressed, 2 = regular. + int state = 0; + while (*src) { + if ((byte) * src >= 128) { + if (state != 0) { + *dst++ = ' '; + } + state = 1; + + // High bit set, replace with common word. + const byte *word = find_uncompressed_string(*src & 0x7f); + // The word is terminated by the final char having its high bit set. + while ((*word & 0x80) == 0) { + *dst++ = *word++; + } + *dst++ = (*word & 0x7f); + } else { + // Otherwise just copy one char. + if (state == 1) { + *dst++ = ' '; + } + state = 2; + + *dst++ = *src; + } + ++src; + } + // Add null-terminator. + *dst = 0; +} + +#endif // MICROPY_ROM_TEXT_COMPRESSION diff --git a/py/qstr.h b/py/qstr.h index 7820de2df9c07..c6c9768d05108 100644 --- a/py/qstr.h +++ b/py/qstr.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -38,38 +38,41 @@ // first entry in enum will be MP_QSTRnull=0, which indicates invalid/no qstr enum { #ifndef NO_QSTR -#define QENUM(id) id, - #include "genhdr/qstrdefs.enum.h" -#undef QENUM +#define QDEF(id, hash, len, str) id, +#define TRANSLATION(english_id, number) + #include "genhdr/qstrdefs.generated.h" +#undef QDEF +#undef TRANSLATION #endif MP_QSTRnumber_of, // no underscore so it can't clash with any of the above }; typedef size_t qstr; +typedef uint16_t qstr_short_t; -typedef struct _qstr_attr_t { - #if MICROPY_QSTR_BYTES_IN_HASH == 1 - uint8_t hash; - #elif MICROPY_QSTR_BYTES_IN_HASH == 2 - uint16_t hash; - #else - #error unimplemented qstr hash decoding - #endif - #if MICROPY_QSTR_BYTES_IN_LEN == 1 - uint8_t len; - #elif MICROPY_QSTR_BYTES_IN_LEN == 2 - uint16_t len; - #else - #error unimplemented qstr length decoding - #endif -} qstr_attr_t; +#if MICROPY_QSTR_BYTES_IN_HASH == 1 +typedef uint8_t qstr_hash_t; +#elif MICROPY_QSTR_BYTES_IN_HASH == 2 +typedef uint16_t qstr_hash_t; +#else +#error unimplemented qstr hash decoding +#endif + +#if MICROPY_QSTR_BYTES_IN_LEN == 1 +typedef uint8_t qstr_len_t; +#elif MICROPY_QSTR_BYTES_IN_LEN == 2 +typedef uint16_t qstr_len_t; +#else +#error unimplemented qstr length decoding +#endif typedef struct _qstr_pool_t { const struct _qstr_pool_t *prev; size_t total_prev_len; size_t alloc; size_t len; - qstr_attr_t *attrs; + qstr_hash_t *hashes; + qstr_len_t *lengths; const char *qstrs[]; } qstr_pool_t; @@ -91,4 +94,9 @@ const byte *qstr_data(qstr q, size_t *len); void qstr_pool_info(size_t *n_pool, size_t *n_qstr, size_t *n_str_data_bytes, size_t *n_total_bytes); void qstr_dump_data(void); +#if MICROPY_ROM_TEXT_COMPRESSION +void mp_decompress_rom_string(byte *dst, mp_rom_error_text_t src); +#define MP_IS_COMPRESSED_ROM_STRING(s) (*(byte *)(s) == 0xff) +#endif + #endif // MICROPY_INCLUDED_PY_QSTR_H diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 70753866bdf50..e1cebb1db397c 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -39,6 +39,10 @@ Q() Q(*) Q(_) Q(/) +#if MICROPY_PY_SYS_PS1_PS2 +Q(>>> ) +Q(... ) +#endif #if MICROPY_PY_BUILTINS_STR_OP_MODULO Q(%#o) Q(%#x) diff --git a/py/reader.c b/py/reader.c index ecc8515662604..d68406b1c68b3 100644 --- a/py/reader.c +++ b/py/reader.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2013-2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/reader.h b/py/reader.h index 6d8565d7b77b2..8511c72ce503b 100644 --- a/py/reader.h +++ b/py/reader.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2013-2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/repl.c b/py/repl.c index 78367e66da9f7..a07dded50cdb5 100644 --- a/py/repl.c +++ b/py/repl.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013-2015 Damien P. George + * Copyright (c) 2013-2015 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,6 +33,16 @@ #if MICROPY_HELPER_REPL +#if MICROPY_PY_SYS_PS1_PS2 +const char *mp_repl_get_psx(unsigned int entry) { + if (mp_obj_is_str(MP_STATE_VM(sys_mutable)[entry])) { + return mp_obj_str_get_str(MP_STATE_VM(sys_mutable)[entry]); + } else { + return ""; + } +} +#endif + STATIC bool str_startswith_word(const char *str, const char *head) { size_t i; for (i = 0; str[i] && head[i]; i++) { @@ -303,10 +313,7 @@ size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print return sizeof(import_str) - 1 - s_len; } } - if (q_first == 0) { - *compl_str = " "; - return s_len ? 0 : 4; - } + return 0; } // 1 match found, or multiple matches with a common prefix diff --git a/py/repl.h b/py/repl.h index 89b64c45f0026..9e8f7f1ddaeb4 100644 --- a/py/repl.h +++ b/py/repl.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -31,8 +31,34 @@ #include "py/mpprint.h" #if MICROPY_HELPER_REPL + +#if MICROPY_PY_SYS_PS1_PS2 + +const char *mp_repl_get_psx(unsigned int entry); + +static inline const char *mp_repl_get_ps1(void) { + return mp_repl_get_psx(MP_SYS_MUTABLE_PS1); +} + +static inline const char *mp_repl_get_ps2(void) { + return mp_repl_get_psx(MP_SYS_MUTABLE_PS2); +} + +#else + +static inline const char *mp_repl_get_ps1(void) { + return ">>> "; +} + +static inline const char *mp_repl_get_ps2(void) { + return "... "; +} + +#endif + bool mp_repl_continue_with_input(const char *input); size_t mp_repl_autocomplete(const char *str, size_t len, const mp_print_t *print, const char **compl_str); + #endif #endif // MICROPY_INCLUDED_PY_REPL_H diff --git a/py/ringbuf.c b/py/ringbuf.c index 5936b64230621..19295afa445e4 100644 --- a/py/ringbuf.c +++ b/py/ringbuf.c @@ -37,8 +37,8 @@ bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t size) { } // Dynamic initialization. This should be accessible from a root pointer.. -bool ringbuf_alloc(ringbuf_t *r, size_t size, bool long_lived) { - bool result = ringbuf_init(r, gc_alloc(size, false, long_lived), size); +bool ringbuf_alloc(ringbuf_t *r, size_t size) { + bool result = ringbuf_init(r, m_malloc(size), size); return result; } diff --git a/py/ringbuf.h b/py/ringbuf.h index 2725bedccafff..b6863599cc6a8 100644 --- a/py/ringbuf.h +++ b/py/ringbuf.h @@ -43,7 +43,7 @@ typedef struct _ringbuf_t { bool ringbuf_init(ringbuf_t *r, uint8_t *buf, size_t capacity); // For allocation of a buffer on the heap, use ringbuf_alloc(). -bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived); +bool ringbuf_alloc(ringbuf_t *r, size_t capacity); // Mark ringbuf as no longer in use, and allow any heap storage to be freed by gc. void ringbuf_deinit(ringbuf_t *r); diff --git a/py/runtime.c b/py/runtime.c index 9bc5f9a584bce..eaeb9eb0acb0f 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014-2018 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -25,10 +25,11 @@ * THE SOFTWARE. */ +#include #include #include #include -#include +#include #include "py/parsenum.h" #include "py/compile.h" @@ -61,13 +62,23 @@ const mp_obj_module_t mp_module___main__ = { .globals = (mp_obj_dict_t *)&MP_STATE_VM(dict_main), }; +MP_REGISTER_MODULE(MP_QSTR___main__, mp_module___main__); + void mp_init(void) { qstr_init(); // no pending exceptions to start with MP_STATE_THREAD(mp_pending_exception) = MP_OBJ_NULL; #if MICROPY_ENABLE_SCHEDULER - MP_STATE_VM(sched_state) = MP_SCHED_IDLE; + #if MICROPY_SCHEDULER_STATIC_NODES + if (MP_STATE_VM(sched_head) == NULL) { + // no pending callbacks to start with + MP_STATE_VM(sched_state) = MP_SCHED_IDLE; + } else { + // pending callbacks are on the list, eg from before a soft reset + MP_STATE_VM(sched_state) = MP_SCHED_PENDING; + } + #endif MP_STATE_VM(sched_idx) = 0; MP_STATE_VM(sched_len) = 0; #endif @@ -135,12 +146,25 @@ void mp_init(void) { MP_STATE_VM(sys_exitfunc) = mp_const_none; #endif + #if MICROPY_PY_SYS_PS1_PS2 + MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS1]) = MP_OBJ_NEW_QSTR(MP_QSTR__gt__gt__gt__space_); + MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS2]) = MP_OBJ_NEW_QSTR(MP_QSTR__dot__dot__dot__space_); + #endif + #if MICROPY_PY_SYS_SETTRACE MP_STATE_THREAD(prof_trace_callback) = MP_OBJ_NULL; MP_STATE_THREAD(prof_callback_is_executing) = false; MP_STATE_THREAD(current_code_state) = NULL; #endif + #if MICROPY_PY_SYS_TRACEBACKLIMIT + MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_TRACEBACKLIMIT]) = MP_OBJ_NEW_SMALL_INT(1000); + #endif + + #if MICROPY_PY_BLUETOOTH + MP_STATE_VM(bluetooth) = MP_OBJ_NULL; + #endif + #if MICROPY_PY_THREAD_GIL mp_thread_mutex_init(&MP_STATE_VM(gil_mutex)); #endif @@ -686,12 +710,11 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ if (have_self) { self = *args++; // may be MP_OBJ_NULL } - uint n_args = n_args_n_kw & 0xff; - uint n_kw = (n_args_n_kw >> 8) & 0xff; - mp_obj_t pos_seq = args[n_args + 2 * n_kw]; // may be MP_OBJ_NULL - mp_obj_t kw_dict = args[n_args + 2 * n_kw + 1]; // may be MP_OBJ_NULL + size_t n_args = n_args_n_kw & 0xff; + size_t n_kw = (n_args_n_kw >> 8) & 0xff; + mp_uint_t star_args = MP_OBJ_SMALL_INT_VALUE(args[n_args + 2 * n_kw]); - DEBUG_OP_printf("call method var (fun=%p, self=%p, n_args=%u, n_kw=%u, args=%p, seq=%p, dict=%p)\n", fun, self, n_args, n_kw, args, pos_seq, kw_dict); + DEBUG_OP_printf("call method var (fun=%p, self=%p, n_args=%u, n_kw=%u, args=%p, map=%u)\n", fun, self, n_args, n_kw, args, star_args); // We need to create the following array of objects: // args[0 .. n_args] unpacked(pos_seq) args[n_args .. n_args + 2 * n_kw] unpacked(kw_dict) @@ -699,19 +722,40 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ // The new args array mp_obj_t *args2; - uint args2_alloc; - uint args2_len = 0; + size_t args2_alloc; + size_t args2_len = 0; + + // Try to get a hint for unpacked * args length + ssize_t list_len = 0; + + if (star_args != 0) { + for (size_t i = 0; i < n_args; i++) { + if ((star_args >> i) & 1) { + mp_obj_t len = mp_obj_len_maybe(args[i]); + if (len != MP_OBJ_NULL) { + // -1 accounts for 1 of n_args occupied by this arg + list_len += mp_obj_get_int(len) - 1; + } + } + } + } // Try to get a hint for the size of the kw_dict - uint kw_dict_len = 0; - if (kw_dict != MP_OBJ_NULL && mp_obj_is_type(kw_dict, &mp_type_dict)) { - kw_dict_len = mp_obj_dict_len(kw_dict); + ssize_t kw_dict_len = 0; + + for (size_t i = 0; i < n_kw; i++) { + mp_obj_t key = args[n_args + i * 2]; + mp_obj_t value = args[n_args + i * 2 + 1]; + if (key == MP_OBJ_NULL && value != MP_OBJ_NULL && mp_obj_is_type(value, &mp_type_dict)) { + // -1 accounts for 1 of n_kw occupied by this arg + kw_dict_len += mp_obj_dict_len(value) - 1; + } } // Extract the pos_seq sequence to the new args array. // Note that it can be arbitrary iterator. - if (pos_seq == MP_OBJ_NULL) { - // no sequence + if (star_args == 0) { + // no star args to unpack // allocate memory for the new array of args args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len); @@ -725,33 +769,11 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ // copy the fixed pos args mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t); args2_len += n_args; - - } else if (mp_obj_is_type(pos_seq, &mp_type_tuple) || mp_obj_is_type(pos_seq, &mp_type_list)) { - // optimise the case of a tuple and list - - // get the items - size_t len; - mp_obj_t *items; - mp_obj_get_array(pos_seq, &len, &items); - - // allocate memory for the new array of args - args2_alloc = 1 + n_args + len + 2 * (n_kw + kw_dict_len); - args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t)); - - // copy the self - if (self != MP_OBJ_NULL) { - args2[args2_len++] = self; - } - - // copy the fixed and variable position args - mp_seq_cat(args2 + args2_len, args, n_args, items, len, mp_obj_t); - args2_len += n_args + len; - } else { - // generic iterator + // at least one star arg to unpack // allocate memory for the new array of args - args2_alloc = 1 + n_args + 2 * (n_kw + kw_dict_len) + 3; + args2_alloc = 1 + n_args + list_len + 2 * (n_kw + kw_dict_len); args2 = mp_nonlocal_alloc(args2_alloc * sizeof(mp_obj_t)); // copy the self @@ -759,84 +781,118 @@ void PLACE_IN_ITCM(mp_call_prepare_args_n_kw_var)(bool have_self, size_t n_args_ args2[args2_len++] = self; } - // copy the fixed position args - mp_seq_copy(args2 + args2_len, args, n_args, mp_obj_t); - args2_len += n_args; - - // extract the variable position args from the iterator - mp_obj_iter_buf_t iter_buf; - mp_obj_t iterable = mp_getiter(pos_seq, &iter_buf); - mp_obj_t item; - while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (args2_len >= args2_alloc) { - args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), args2_alloc * 2 * sizeof(mp_obj_t)); - args2_alloc *= 2; + for (size_t i = 0; i < n_args; i++) { + mp_obj_t arg = args[i]; + if ((star_args >> i) & 1) { + // star arg + if (mp_obj_is_type(arg, &mp_type_tuple) || mp_obj_is_type(arg, &mp_type_list)) { + // optimise the case of a tuple and list + + // get the items + size_t len; + mp_obj_t *items; + mp_obj_get_array(arg, &len, &items); + + // copy the items + assert(args2_len + len <= args2_alloc); + mp_seq_copy(args2 + args2_len, items, len, mp_obj_t); + args2_len += len; + } else { + // generic iterator + + // extract the variable position args from the iterator + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(arg, &iter_buf); + mp_obj_t item; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (args2_len >= args2_alloc) { + args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), + args2_alloc * 2 * sizeof(mp_obj_t)); + args2_alloc *= 2; + } + args2[args2_len++] = item; + } + } + } else { + // normal argument + assert(args2_len < args2_alloc); + args2[args2_len++] = arg; } - args2[args2_len++] = item; } } // The size of the args2 array now is the number of positional args. - uint pos_args_len = args2_len; - - // Copy the fixed kw args. - mp_seq_copy(args2 + args2_len, args + n_args, 2 * n_kw, mp_obj_t); - args2_len += 2 * n_kw; + size_t pos_args_len = args2_len; + + // ensure there is still enough room for kw args + if (args2_len + 2 * (n_kw + kw_dict_len) > args2_alloc) { + size_t new_alloc = args2_len + 2 * (n_kw + kw_dict_len); + args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), + new_alloc * sizeof(mp_obj_t)); + args2_alloc = new_alloc; + } - // Extract (key,value) pairs from kw_dict dictionary and append to args2. - // Note that it can be arbitrary iterator. - if (kw_dict == MP_OBJ_NULL) { - // pass - } else if (mp_obj_is_type(kw_dict, &mp_type_dict)) { - // dictionary - mp_map_t *map = mp_obj_dict_get_map(kw_dict); - assert(args2_len + 2 * map->used <= args2_alloc); // should have enough, since kw_dict_len is in this case hinted correctly above - for (size_t i = 0; i < map->alloc; i++) { - if (mp_map_slot_is_filled(map, i)) { - // the key must be a qstr, so intern it if it's a string - mp_obj_t key = map->table[i].key; - if (!mp_obj_is_qstr(key)) { - key = mp_obj_str_intern_checked(key); - } - args2[args2_len++] = key; - args2[args2_len++] = map->table[i].value; - } - } - } else { - // generic mapping: - // - call keys() to get an iterable of all keys in the mapping - // - call __getitem__ for each key to get the corresponding value - - // get the keys iterable - mp_obj_t dest[3]; - mp_load_method(kw_dict, MP_QSTR_keys, dest); - mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest), NULL); - - mp_obj_t key; - while ((key = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - // expand size of args array if needed - if (args2_len + 1 >= args2_alloc) { - uint new_alloc = args2_alloc * 2; - if (new_alloc < 4) { - new_alloc = 4; + // Copy the kw args. + for (size_t i = 0; i < n_kw; i++) { + mp_obj_t kw_key = args[n_args + i * 2]; + mp_obj_t kw_value = args[n_args + i * 2 + 1]; + if (kw_key == MP_OBJ_NULL) { + // double-star args + if (mp_obj_is_type(kw_value, &mp_type_dict)) { + // dictionary + mp_map_t *map = mp_obj_dict_get_map(kw_value); + // should have enough, since kw_dict_len is in this case hinted correctly above + assert(args2_len + 2 * map->used <= args2_alloc); + for (size_t j = 0; j < map->alloc; j++) { + if (mp_map_slot_is_filled(map, j)) { + // the key must be a qstr, so intern it if it's a string + mp_obj_t key = map->table[j].key; + if (!mp_obj_is_qstr(key)) { + key = mp_obj_str_intern_checked(key); + } + args2[args2_len++] = key; + args2[args2_len++] = map->table[j].value; + } } - args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), new_alloc * sizeof(mp_obj_t)); - args2_alloc = new_alloc; - } + } else { + // generic mapping: + // - call keys() to get an iterable of all keys in the mapping + // - call __getitem__ for each key to get the corresponding value + + // get the keys iterable + mp_obj_t dest[3]; + mp_load_method(kw_value, MP_QSTR_keys, dest); + mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest), NULL); + + mp_obj_t key; + while ((key = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + // expand size of args array if needed + if (args2_len + 1 >= args2_alloc) { + size_t new_alloc = args2_alloc * 2; + args2 = mp_nonlocal_realloc(args2, args2_alloc * sizeof(mp_obj_t), new_alloc * sizeof(mp_obj_t)); + args2_alloc = new_alloc; + } - // the key must be a qstr, so intern it if it's a string - if (!mp_obj_is_qstr(key)) { - key = mp_obj_str_intern_checked(key); - } + // the key must be a qstr, so intern it if it's a string + if (!mp_obj_is_qstr(key)) { + key = mp_obj_str_intern_checked(key); + } - // get the value corresponding to the key - mp_load_method(kw_dict, MP_QSTR___getitem__, dest); - dest[2] = key; - mp_obj_t value = mp_call_method_n_kw(1, 0, dest); + // get the value corresponding to the key + mp_load_method(kw_value, MP_QSTR___getitem__, dest); + dest[2] = key; + mp_obj_t value = mp_call_method_n_kw(1, 0, dest); - // store the key/value pair in the argument array - args2[args2_len++] = key; - args2[args2_len++] = value; + // store the key/value pair in the argument array + args2[args2_len++] = key; + args2[args2_len++] = value; + } + } + } else { + // normal kwarg + assert(args2_len + 2 <= args2_alloc); + args2[args2_len++] = kw_key; + args2[args2_len++] = kw_value; } } @@ -858,7 +914,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ob } // unpacked items are stored in reverse order into the array pointed to by items -void __attribute__((noinline,)) mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { +void __attribute__((noinline, )) mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { size_t seq_len; if (mp_obj_is_type(seq_in, &mp_type_tuple) || mp_obj_is_type(seq_in, &mp_type_list)) { mp_obj_t *seq_items; @@ -1018,8 +1074,7 @@ STATIC const mp_obj_type_t mp_type_checked_fun = { }; STATIC mp_obj_t mp_obj_new_checked_fun(const mp_obj_type_t *type, mp_obj_t fun) { - mp_obj_checked_fun_t *o = m_new_obj(mp_obj_checked_fun_t); - o->base.type = &mp_type_checked_fun; + mp_obj_checked_fun_t *o = mp_obj_malloc(mp_obj_checked_fun_t, &mp_type_checked_fun); o->type = type; o->fun = fun; return MP_OBJ_FROM_PTR(o); @@ -1360,7 +1415,12 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th assert((send_value != MP_OBJ_NULL) ^ (throw_value != MP_OBJ_NULL)); const mp_obj_type_t *type = mp_obj_get_type(self_in); - if (type == &mp_type_gen_instance) { + // CIRCUITPY distinguishes generators and coroutines. + if (type == &mp_type_gen_instance + #if MICROPY_PY_ASYNC_AWAIT + || type == &mp_type_coro_instance + #endif + ) { return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val); } @@ -1482,7 +1542,7 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) { return mp_builtin___import__(5, args); } -mp_obj_t __attribute__((noinline,)) mp_import_from(mp_obj_t module, qstr name) { +mp_obj_t __attribute__((noinline, )) mp_import_from(mp_obj_t module, qstr name) { DEBUG_printf("import from %p %s\n", module, qstr_str(name)); mp_obj_t dest[2]; @@ -1634,7 +1694,7 @@ NORETURN MP_COLD void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, const co NORETURN MP_COLD void mp_raise_msg_varg(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(exc_type, fmt, argptr); va_end(argptr); } @@ -1657,7 +1717,7 @@ NORETURN MP_COLD void mp_raise_RuntimeError(const compressed_string_t *msg) { NORETURN MP_COLD void mp_raise_RuntimeError_varg(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_RuntimeError, fmt, argptr); va_end(argptr); } @@ -1672,7 +1732,7 @@ NORETURN MP_COLD void mp_raise_IndexError(const compressed_string_t *msg) { NORETURN MP_COLD void mp_raise_IndexError_varg(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_IndexError, fmt, argptr); va_end(argptr); } @@ -1683,7 +1743,7 @@ NORETURN MP_COLD void mp_raise_ValueError(const compressed_string_t *msg) { NORETURN MP_COLD void mp_raise_ValueError_varg(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_ValueError, fmt, argptr); va_end(argptr); } @@ -1694,7 +1754,7 @@ NORETURN MP_COLD void mp_raise_TypeError(const compressed_string_t *msg) { NORETURN MP_COLD void mp_raise_TypeError_varg(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_TypeError, fmt, argptr); va_end(argptr); } @@ -1713,7 +1773,7 @@ NORETURN MP_COLD void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { NORETURN MP_COLD void mp_raise_OSError_msg_varg(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_OSError, fmt, argptr); va_end(argptr); } @@ -1732,7 +1792,7 @@ NORETURN MP_COLD void mp_raise_NotImplementedError(const compressed_string_t *ms NORETURN MP_COLD void mp_raise_NotImplementedError_varg(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_NotImplementedError, fmt, argptr); va_end(argptr); } @@ -1740,7 +1800,7 @@ NORETURN MP_COLD void mp_raise_NotImplementedError_varg(const compressed_string_ NORETURN MP_COLD void mp_raise_OverflowError_varg(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_OverflowError, fmt, argptr); va_end(argptr); } diff --git a/py/runtime.h b/py/runtime.h index d870bbc634078..5ecab91e99ab8 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -63,6 +63,15 @@ typedef struct _mp_arg_t { mp_arg_val_t defval; } mp_arg_t; +struct _mp_sched_node_t; + +typedef void (*mp_sched_callback_t)(struct _mp_sched_node_t *); + +typedef struct _mp_sched_node_t { + mp_sched_callback_t callback; + struct _mp_sched_node_t *next; +} mp_sched_node_t; + // Tables mapping operator enums to qstrs, defined in objtype.c extern const byte mp_unary_op_method_name[]; extern const byte mp_binary_op_method_name[]; @@ -80,6 +89,7 @@ void mp_sched_lock(void); void mp_sched_unlock(void); #define mp_sched_num_pending() (MP_STATE_VM(sched_len)) bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg); +bool mp_sched_schedule_node(mp_sched_node_t *node, mp_sched_callback_t callback); #endif // extra printing method specifically for mp_obj_t's which are integral type diff --git a/py/runtime0.h b/py/runtime0.h index 9af108d8b370e..218820fd70ac6 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -29,6 +29,7 @@ // The first four must fit in 8 bits, see emitbc.c // The remaining must fit in 16 bits, see scope.h +// and must match definitions in mpy-tool.py and mpy_ld.py #define MP_SCOPE_FLAG_ALL_SIG (0x1f) #define MP_SCOPE_FLAG_GENERATOR (0x01) #define MP_SCOPE_FLAG_VARKEYWORDS (0x02) diff --git a/py/scheduler.c b/py/scheduler.c index 1fd5daeab19f0..2aa28bd335145 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -90,6 +90,24 @@ void mp_handle_pending(bool raise_exc) { // or by the VM's inlined version of that function. void mp_handle_pending_tail(mp_uint_t atomic_state) { MP_STATE_VM(sched_state) = MP_SCHED_LOCKED; + + #if MICROPY_SCHEDULER_STATIC_NODES + // Run all pending C callbacks. + while (MP_STATE_VM(sched_head) != NULL) { + mp_sched_node_t *node = MP_STATE_VM(sched_head); + MP_STATE_VM(sched_head) = node->next; + if (MP_STATE_VM(sched_head) == NULL) { + MP_STATE_VM(sched_tail) = NULL; + } + mp_sched_callback_t callback = node->callback; + node->callback = NULL; + MICROPY_END_ATOMIC_SECTION(atomic_state); + callback(node); + atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + } + #endif + + // Run at most one pending Python callback. if (!mp_sched_empty()) { mp_sched_item_t item = MP_STATE_VM(sched_queue)[MP_STATE_VM(sched_idx)]; MP_STATE_VM(sched_idx) = IDX_MASK(MP_STATE_VM(sched_idx) + 1); @@ -99,6 +117,7 @@ void mp_handle_pending_tail(mp_uint_t atomic_state) { } else { MICROPY_END_ATOMIC_SECTION(atomic_state); } + mp_sched_unlock(); } @@ -117,7 +136,11 @@ void mp_sched_unlock(void) { assert(MP_STATE_VM(sched_state) < 0); if (++MP_STATE_VM(sched_state) == 0) { // vm became unlocked - if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL || mp_sched_num_pending()) { + if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL + #if MICROPY_SCHEDULER_STATIC_NODES + || MP_STATE_VM(sched_head) != NULL + #endif + || mp_sched_num_pending()) { MP_STATE_VM(sched_state) = MP_SCHED_PENDING; } else { MP_STATE_VM(sched_state) = MP_SCHED_IDLE; @@ -146,6 +169,33 @@ bool MICROPY_WRAP_MP_SCHED_SCHEDULE(mp_sched_schedule)(mp_obj_t function, mp_obj return ret; } +#if MICROPY_SCHEDULER_STATIC_NODES +bool mp_sched_schedule_node(mp_sched_node_t *node, mp_sched_callback_t callback) { + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + bool ret; + if (node->callback == NULL) { + if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) { + MP_STATE_VM(sched_state) = MP_SCHED_PENDING; + } + node->callback = callback; + node->next = NULL; + if (MP_STATE_VM(sched_tail) == NULL) { + MP_STATE_VM(sched_head) = node; + } else { + MP_STATE_VM(sched_tail)->next = node; + } + MP_STATE_VM(sched_tail) = node; + MICROPY_SCHED_HOOK_SCHEDULED; + ret = true; + } else { + // already scheduled + ret = false; + } + MICROPY_END_ATOMIC_SECTION(atomic_state); + return ret; +} +#endif + #else // MICROPY_ENABLE_SCHEDULER // A variant of this is inlined in the VM at the pending exception check diff --git a/py/scope.c b/py/scope.c index f9308267d3d91..8fc0943289b4f 100644 --- a/py/scope.c +++ b/py/scope.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -40,7 +40,7 @@ STATIC const uint8_t scope_simple_name_table[] = { [SCOPE_GEN_EXPR] = MP_QSTR__lt_genexpr_gt_, }; -scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, mp_uint_t emit_options) { +scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, mp_uint_t emit_options) { // Make sure those qstrs indeed fit in an uint8_t. MP_STATIC_ASSERT(MP_QSTR__lt_module_gt_ <= UINT8_MAX); MP_STATIC_ASSERT(MP_QSTR__lt_lambda_gt_ <= UINT8_MAX); @@ -52,7 +52,6 @@ scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, mp_u scope_t *scope = m_new0(scope_t, 1); scope->kind = kind; scope->pn = pn; - scope->source_file = source_file; if (kind == SCOPE_FUNCTION || kind == SCOPE_CLASS) { assert(MP_PARSE_NODE_IS_STRUCT(pn)); scope->simple_name = MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t *)pn)->nodes[0]); diff --git a/py/scope.h b/py/scope.h index b189260a37a6b..e7d2a304f79f3 100644 --- a/py/scope.h +++ b/py/scope.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,6 +32,7 @@ typedef enum { ID_INFO_KIND_UNDECIDED, ID_INFO_KIND_GLOBAL_IMPLICIT, + ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED, ID_INFO_KIND_GLOBAL_EXPLICIT, ID_INFO_KIND_LOCAL, // in a function f, written and only referenced by f ID_INFO_KIND_CELL, // in a function f, read/written by children of f @@ -75,7 +76,6 @@ typedef struct _scope_t { struct _scope_t *next; mp_parse_node_t pn; mp_raw_code_t *raw_code; - uint16_t source_file; // a qstr uint16_t simple_name; // a qstr uint16_t scope_flags; // see runtime0.h uint16_t emit_options; // see emitglue.h @@ -90,7 +90,7 @@ typedef struct _scope_t { id_info_t *id_info; } scope_t; -scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, mp_uint_t emit_options); +scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, mp_uint_t emit_options); void scope_free(scope_t *scope); id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, id_info_kind_t kind); id_info_t *scope_find(scope_t *scope, qstr qstr); diff --git a/py/sequence.c b/py/sequence.c index 42a9a4a0ae18b..faed55872351e 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/py/showbc.c b/py/showbc.c index 1d02b559b0963..f9c334b93bbbb 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,7 +28,7 @@ #include #include "py/bc0.h" -#include "py/bc.h" +#include "py/emitglue.h" #if MICROPY_DEBUG_PRINTERS @@ -38,80 +38,90 @@ unum = (unum << 7) + (*ip & 0x7f); \ } while ((*ip++ & 0x80) != 0); \ } -#define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0) -#define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0) -#if MICROPY_PERSISTENT_CODE +#define DECODE_ULABEL \ + do { \ + if (ip[0] & 0x80) { \ + unum = ((ip[0] & 0x7f) | (ip[1] << 7)); \ + ip += 2; \ + } else { \ + unum = ip[0]; \ + ip += 1; \ + } \ + } while (0) + +#define DECODE_SLABEL \ + do { \ + if (ip[0] & 0x80) { \ + unum = ((ip[0] & 0x7f) | (ip[1] << 7)) - 0x4000; \ + ip += 2; \ + } else { \ + unum = ip[0] - 0x40; \ + ip += 1; \ + } \ + } while (0) + +#if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE #define DECODE_QSTR \ - qst = ip[0] | ip[1] << 8; \ - ip += 2; -#define DECODE_PTR \ - DECODE_UINT; \ - unum = mp_showbc_const_table[unum] -#define DECODE_OBJ \ DECODE_UINT; \ - unum = mp_showbc_const_table[unum] + qst = qstr_table[unum] #else -#define DECODE_QSTR { \ - qst = 0; \ - do { \ - qst = (qst << 7) + (*ip & 0x7f); \ - } while ((*ip++ & 0x80) != 0); \ -} -#define DECODE_PTR do { \ - ip = (byte *)MP_ALIGN(ip, sizeof(void *)); \ - unum = (uintptr_t)*(void **)ip; \ - ip += sizeof(void *); \ -} while (0) -#define DECODE_OBJ do { \ - ip = (byte *)MP_ALIGN(ip, sizeof(mp_obj_t)); \ - unum = (mp_uint_t)*(mp_obj_t *)ip; \ - ip += sizeof(mp_obj_t); \ -} while (0) +#define DECODE_QSTR \ + DECODE_UINT; \ + qst = unum; #endif -const byte *mp_showbc_code_start; -const mp_uint_t *mp_showbc_const_table; +#define DECODE_PTR \ + DECODE_UINT; \ + unum = (mp_uint_t)(uintptr_t)child_table[unum] -void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *ip, mp_uint_t len, const mp_uint_t *const_table) { - mp_showbc_code_start = ip; +#define DECODE_OBJ \ + DECODE_UINT; \ + unum = (mp_uint_t)obj_table[unum] + +void mp_bytecode_print(const mp_print_t *print, const mp_raw_code_t *rc, const mp_module_constants_t *cm) { + const byte *ip_start = rc->fun_data; + const byte *ip = rc->fun_data; // Decode prelude MP_BC_PRELUDE_SIG_DECODE(ip); MP_BC_PRELUDE_SIZE_DECODE(ip); const byte *code_info = ip; - #if MICROPY_PERSISTENT_CODE - qstr block_name = code_info[0] | (code_info[1] << 8); - qstr source_file = code_info[2] | (code_info[3] << 8); - code_info += 4; - #else qstr block_name = mp_decode_uint(&code_info); - qstr source_file = mp_decode_uint(&code_info); + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + block_name = cm->qstr_table[block_name]; + qstr source_file = cm->qstr_table[0]; + #else + qstr source_file = cm->source_file; #endif - mp_printf(print, "File %s, code block '%s' (descriptor: %p, bytecode @%p " UINT_FMT " bytes)\n", - qstr_str(source_file), qstr_str(block_name), descr, mp_showbc_code_start, len); + mp_printf(print, "File %s, code block '%s' (descriptor: %p, bytecode @%p %u bytes)\n", + qstr_str(source_file), qstr_str(block_name), rc, ip_start, (unsigned)rc->fun_data_len); // raw bytecode dump - size_t prelude_size = ip - mp_showbc_code_start + n_info + n_cell; + size_t prelude_size = ip - ip_start + n_info + n_cell; mp_printf(print, "Raw bytecode (code_info_size=%u, bytecode_size=%u):\n", - (unsigned)prelude_size, (unsigned)(len - prelude_size)); - for (mp_uint_t i = 0; i < len; i++) { + (unsigned)prelude_size, (unsigned)(rc->fun_data_len - prelude_size)); + for (size_t i = 0; i < rc->fun_data_len; i++) { if (i > 0 && i % 16 == 0) { mp_printf(print, "\n"); } - mp_printf(print, " %02x", mp_showbc_code_start[i]); + mp_printf(print, " %02x", ip_start[i]); } mp_printf(print, "\n"); // bytecode prelude: arg names (as qstr objects) mp_printf(print, "arg names:"); for (mp_uint_t i = 0; i < n_pos_args + n_kwonly_args; i++) { - mp_printf(print, " %s", qstr_str(MP_OBJ_QSTR_VALUE(const_table[i]))); + qstr qst = mp_decode_uint(&code_info); + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + qst = cm->qstr_table[qst]; + #endif + mp_printf(print, " %s", qstr_str(qst)); } mp_printf(print, "\n"); @@ -120,6 +130,7 @@ void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *i // skip over code_info ip += n_info; + const byte *line_info_top = ip; // bytecode prelude: initialise closed over variables for (size_t i = 0; i < n_cell; ++i) { @@ -132,7 +143,7 @@ void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *i mp_int_t bc = 0; mp_uint_t source_line = 1; mp_printf(print, " bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line); - for (const byte *ci = code_info; *ci;) { + for (const byte *ci = code_info; ci < line_info_top;) { if ((ci[0] & 0x80) == 0) { // 0b0LLBBBBB encoding bc += ci[0] & 0x1f; @@ -147,10 +158,14 @@ void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *i mp_printf(print, " bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line); } } - mp_bytecode_print2(print, ip, len - prelude_size, const_table); + mp_bytecode_print2(print, ip, rc->fun_data_len - prelude_size, rc->children, cm); } -const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { +const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip_start, const byte *ip, mp_raw_code_t *const *child_table, const mp_module_constants_t *cm) { + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + const qstr_short_t *qstr_table = cm->qstr_table; + #endif + const mp_obj_t *obj_table = cm->obj_table; mp_uint_t unum; qstr qst; @@ -309,32 +324,32 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { case MP_BC_JUMP: DECODE_SLABEL; - mp_printf(print, "JUMP " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "JUMP " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_POP_JUMP_IF_TRUE: DECODE_SLABEL; - mp_printf(print, "POP_JUMP_IF_TRUE " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "POP_JUMP_IF_TRUE " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_POP_JUMP_IF_FALSE: DECODE_SLABEL; - mp_printf(print, "POP_JUMP_IF_FALSE " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "POP_JUMP_IF_FALSE " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_JUMP_IF_TRUE_OR_POP: - DECODE_SLABEL; - mp_printf(print, "JUMP_IF_TRUE_OR_POP " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + DECODE_ULABEL; + mp_printf(print, "JUMP_IF_TRUE_OR_POP " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_JUMP_IF_FALSE_OR_POP: - DECODE_SLABEL; - mp_printf(print, "JUMP_IF_FALSE_OR_POP " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + DECODE_ULABEL; + mp_printf(print, "JUMP_IF_FALSE_OR_POP " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_SETUP_WITH: DECODE_ULABEL; // loop-like labels are always forward - mp_printf(print, "SETUP_WITH " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "SETUP_WITH " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_WITH_CLEANUP: @@ -343,18 +358,18 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { case MP_BC_UNWIND_JUMP: DECODE_SLABEL; - mp_printf(print, "UNWIND_JUMP " UINT_FMT " %d", (mp_uint_t)(ip + unum - mp_showbc_code_start), *ip); + mp_printf(print, "UNWIND_JUMP " UINT_FMT " %d", (mp_uint_t)(ip + unum - ip_start), *ip); ip += 1; break; case MP_BC_SETUP_EXCEPT: DECODE_ULABEL; // except labels are always forward - mp_printf(print, "SETUP_EXCEPT " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "SETUP_EXCEPT " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_SETUP_FINALLY: DECODE_ULABEL; // except labels are always forward - mp_printf(print, "SETUP_FINALLY " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "SETUP_FINALLY " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_END_FINALLY: @@ -375,12 +390,12 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { case MP_BC_FOR_ITER: DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward - mp_printf(print, "FOR_ITER " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "FOR_ITER " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_POP_EXCEPT_JUMP: DECODE_ULABEL; // these labels are always forward - mp_printf(print, "POP_EXCEPT_JUMP " UINT_FMT, (mp_uint_t)(ip + unum - mp_showbc_code_start)); + mp_printf(print, "POP_EXCEPT_JUMP " UINT_FMT, (mp_uint_t)(ip + unum - ip_start)); break; case MP_BC_BUILD_TUPLE: @@ -535,12 +550,11 @@ const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip) { return ip; } -void mp_bytecode_print2(const mp_print_t *print, const byte *ip, size_t len, const mp_uint_t *const_table) { - mp_showbc_code_start = ip; - mp_showbc_const_table = const_table; - while (ip < len + mp_showbc_code_start) { - mp_printf(print, "%02u ", (uint)(ip - mp_showbc_code_start)); - ip = mp_bytecode_print_str(print, ip); +void mp_bytecode_print2(const mp_print_t *print, const byte *ip, size_t len, mp_raw_code_t *const *child_table, const mp_module_constants_t *cm) { + const byte *ip_start = ip; + while (ip < ip_start + len) { + mp_printf(print, "%02u ", (uint)(ip - ip_start)); + ip = mp_bytecode_print_str(print, ip_start, ip, child_table, cm); mp_printf(print, "\n"); } } diff --git a/py/smallint.c b/py/smallint.c index 9124b76c137d8..aa542ca7bf29a 100644 --- a/py/smallint.c +++ b/py/smallint.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/smallint.h b/py/smallint.h index 2fcd3fb2963eb..584e0018d1ba3 100644 --- a/py/smallint.h +++ b/py/smallint.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -61,6 +61,13 @@ #define MP_SMALL_INT_MAX ((mp_int_t)(~(MP_SMALL_INT_MIN))) +// https://stackoverflow.com/a/4589384/1976323 +// Number of bits in inttype_MAX, or in any (1<state[0] + 1)) #endif -#define TRACE(ip) TRACE_PREFIX; mp_bytecode_print2(&mp_plat_print, ip, 1, code_state->fun_bc->const_table); +#define TRACE(ip) TRACE_PREFIX; mp_bytecode_print2(&mp_plat_print, ip, 1, code_state->fun_bc->child_table, &code_state->fun_bc->context->constants); #else #define TRACE(ip) #endif @@ -64,38 +64,53 @@ do { \ unum = (unum << 7) + (*ip & 0x7f); \ } while ((*ip++ & 0x80) != 0) -#define DECODE_ULABEL size_t ulab = (ip[0] | (ip[1] << 8)); ip += 2 -#define DECODE_SLABEL size_t slab = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2 -#if MICROPY_PERSISTENT_CODE +#define DECODE_ULABEL \ + size_t ulab; \ + do { \ + if (ip[0] & 0x80) { \ + ulab = ((ip[0] & 0x7f) | (ip[1] << 7)); \ + ip += 2; \ + } else { \ + ulab = ip[0]; \ + ip += 1; \ + } \ + } while (0) + +#define DECODE_SLABEL \ + size_t slab; \ + do { \ + if (ip[0] & 0x80) { \ + slab = ((ip[0] & 0x7f) | (ip[1] << 7)) - 0x4000; \ + ip += 2; \ + } else { \ + slab = ip[0] - 0x40; \ + ip += 1; \ + } \ + } while (0) + +#if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE #define DECODE_QSTR \ - qstr qst = ip[0] | ip[1] << 8; \ - ip += 2; -#define DECODE_PTR \ DECODE_UINT; \ - void *ptr = (void*)(uintptr_t)code_state->fun_bc->const_table[unum] -#define DECODE_OBJ \ - DECODE_UINT; \ - mp_obj_t obj = (mp_obj_t)code_state->fun_bc->const_table[unum] + qstr qst = qstr_table[unum] #else -#define DECODE_QSTR qstr qst = 0; \ - do { \ - qst = (qst << 7) + (*ip & 0x7f); \ - } while ((*ip++ & 0x80) != 0) -#define DECODE_PTR \ - ip = (byte*)MP_ALIGN(ip, sizeof(void*)); \ - void *ptr = *(void**)ip; \ - ip += sizeof(void*) -#define DECODE_OBJ \ - ip = (byte*)MP_ALIGN(ip, sizeof(mp_obj_t)); \ - mp_obj_t obj = *(mp_obj_t*)ip; \ - ip += sizeof(mp_obj_t) +#define DECODE_QSTR \ + DECODE_UINT; \ + qstr qst = unum; #endif +#define DECODE_PTR \ + DECODE_UINT; \ + void *ptr = (void *)(uintptr_t)code_state->fun_bc->child_table[unum] + +#define DECODE_OBJ \ + DECODE_UINT; \ + mp_obj_t obj = (mp_obj_t)code_state->fun_bc->context->constants.obj_table[unum] + #define PUSH(val) *++sp = (val) #define POP() (*sp--) #define TOP() (*sp) @@ -277,6 +292,9 @@ FRAME_SETUP(); // local variables that are not visible to the exception handler const byte *ip = code_state->ip; mp_obj_t *sp = code_state->sp; + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + const qstr_short_t *qstr_table = code_state->fun_bc->context->constants.qstr_table; + #endif mp_obj_t obj_shared; MICROPY_VM_HOOK_INIT @@ -564,9 +582,9 @@ FRAME_SETUP(); } ENTRY(MP_BC_JUMP_IF_TRUE_OR_POP): { - DECODE_SLABEL; + DECODE_ULABEL; if (mp_obj_is_true(TOP())) { - ip += slab; + ip += ulab; } else { sp--; } @@ -574,11 +592,11 @@ FRAME_SETUP(); } ENTRY(MP_BC_JUMP_IF_FALSE_OR_POP): { - DECODE_SLABEL; + DECODE_ULABEL; if (mp_obj_is_true(TOP())) { sp--; } else { - ip += slab; + ip += ulab; } DISPATCH_WITH_PEND_EXC_CHECK(); } @@ -881,15 +899,15 @@ unwind_jump:; ENTRY(MP_BC_MAKE_FUNCTION): { DECODE_PTR; - PUSH(mp_make_function_from_raw_code(ptr, MP_OBJ_NULL, MP_OBJ_NULL)); + PUSH(mp_make_function_from_raw_code(ptr, code_state->fun_bc->context, NULL)); DISPATCH(); } ENTRY(MP_BC_MAKE_FUNCTION_DEFARGS): { DECODE_PTR; // Stack layout: def_tuple def_dict <- TOS - mp_obj_t def_dict = POP(); - SET_TOP(mp_make_function_from_raw_code(ptr, TOP(), def_dict)); + sp -= 1; + SET_TOP(mp_make_function_from_raw_code(ptr, code_state->fun_bc->context, sp)); DISPATCH(); } @@ -898,7 +916,7 @@ unwind_jump:; size_t n_closed_over = *ip++; // Stack layout: closed_overs <- TOS sp -= n_closed_over - 1; - SET_TOP(mp_make_closure_from_raw_code(ptr, n_closed_over, sp)); + SET_TOP(mp_make_closure_from_raw_code(ptr, code_state->fun_bc->context, n_closed_over, sp)); DISPATCH(); } @@ -907,7 +925,7 @@ unwind_jump:; size_t n_closed_over = *ip++; // Stack layout: def_tuple def_dict closed_overs <- TOS sp -= 2 + n_closed_over - 1; - SET_TOP(mp_make_closure_from_raw_code(ptr, 0x100 | n_closed_over, sp)); + SET_TOP(mp_make_closure_from_raw_code(ptr, code_state->fun_bc->context, 0x100 | n_closed_over, sp)); DISPATCH(); } @@ -953,8 +971,8 @@ unwind_jump:; // unum & 0xff == n_positional // (unum >> 8) & 0xff == n_keyword // We have following stack layout here: - // fun arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS - sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 2; + // fun arg0 arg1 ... kw0 val0 kw1 val1 ... bitmap <- TOS + sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 1; #if MICROPY_STACKLESS if (mp_obj_get_type(*sp) == &mp_type_fun_bc) { code_state->ip = ip; @@ -1038,8 +1056,8 @@ unwind_jump:; // unum & 0xff == n_positional // (unum >> 8) & 0xff == n_keyword // We have following stack layout here: - // fun self arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS - sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 3; + // fun self arg0 arg1 ... kw0 val0 kw1 val1 ... bitmap <- TOS + sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 2; #if MICROPY_STACKLESS if (mp_obj_get_type(*sp) == &mp_type_fun_bc) { code_state->ip = ip; @@ -1419,23 +1437,20 @@ unwind_jump:; const byte *ip = code_state->fun_bc->bytecode; MP_BC_PRELUDE_SIG_DECODE(ip); MP_BC_PRELUDE_SIZE_DECODE(ip); + const byte *line_info_top = ip + n_info; const byte *bytecode_start = ip + n_info + n_cell; - #if !MICROPY_PERSISTENT_CODE - // so bytecode is aligned - bytecode_start = MP_ALIGN(bytecode_start, sizeof(mp_uint_t)); - #endif size_t bc = code_state->ip - bytecode_start; - #if MICROPY_PERSISTENT_CODE - qstr block_name = ip[0] | (ip[1] << 8); - qstr source_file = ip[2] | (ip[3] << 8); - ip += 4; - #else qstr block_name = mp_decode_uint_value(ip); - ip = mp_decode_uint_skip(ip); - qstr source_file = mp_decode_uint_value(ip); - ip = mp_decode_uint_skip(ip); + for (size_t i = 0; i < 1 + n_pos_args + n_kwonly_args; ++i) { + ip = mp_decode_uint_skip(ip); + } + #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE + block_name = code_state->fun_bc->context->constants.qstr_table[block_name]; + qstr source_file = code_state->fun_bc->context->constants.qstr_table[0]; + #else + qstr source_file = code_state->fun_bc->context->constants.source_file; #endif - size_t source_line = mp_bytecode_get_source_line(ip, bc); + size_t source_line = mp_bytecode_get_source_line(ip, line_info_top, bc); mp_obj_exception_add_traceback(MP_OBJ_FROM_PTR(nlr.ret_val), source_file, source_line, block_name); } diff --git a/py/vmentrytable.h b/py/vmentrytable.h index b270dc9845f5d..8b8781de93cac 100644 --- a/py/vmentrytable.h +++ b/py/vmentrytable.h @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/vstr.c b/py/vstr.c index acc957e778cc4..ef5fe06eb2c97 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2014 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/py/warning.c b/py/warning.c index 71a3ac59abbae..cba21ba6c927c 100644 --- a/py/warning.c +++ b/py/warning.c @@ -3,8 +3,8 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2014 Damien P. George - * SPDX-FileCopyrightText: Copyright (c) 2015-2018 Paul Sokolovsky + * Copyright (c) 2014 Damien P. George + * Copyright (c) 2015-2018 Paul Sokolovsky * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal diff --git a/shared-bindings/__future__/__init__.c b/shared-bindings/__future__/__init__.c index ad1bb3b2838d5..dfef2204ca620 100644 --- a/shared-bindings/__future__/__init__.c +++ b/shared-bindings/__future__/__init__.c @@ -57,4 +57,4 @@ const mp_obj_module_t future_module = { .globals = (mp_obj_dict_t *)&future_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR___future__, future_module, CIRCUITPY_FUTURE); +MP_REGISTER_MODULE(MP_QSTR___future__, future_module); diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c index 236ca9e39eb72..cae1b9a235b77 100644 --- a/shared-bindings/_bleio/Address.c +++ b/shared-bindings/_bleio/Address.c @@ -56,8 +56,7 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t); - self->base.type = &bleio_address_type; + bleio_address_obj_t *self = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); const mp_obj_t address = args[ARG_address].u_obj; mp_buffer_info_t buf_info; diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c index 823250c365102..1f752577c188f 100644 --- a/shared-bindings/_bleio/Characteristic.c +++ b/shared-bindings/_bleio/Characteristic.c @@ -141,8 +141,8 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_ user_description = mp_obj_str_get_str(args[ARG_user_description].u_obj); } - bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t); - characteristic->base.type = &bleio_characteristic_type; + bleio_characteristic_obj_t *characteristic = + mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); // Range checking on max_length arg is done by the common_hal layer, because // it may vary depending on underlying BLE implementation. diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c index 1efb992c723dd..842ea4cc58cd0 100644 --- a/shared-bindings/_bleio/CharacteristicBuffer.c +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -74,8 +74,8 @@ STATIC mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, const mp_int_t buffer_size = mp_arg_validate_int_min(args[ARG_buffer_size].u_int, 1, MP_QSTR_buffer_size); - bleio_characteristic_buffer_obj_t *self = m_new_obj(bleio_characteristic_buffer_obj_t); - self->base.type = &bleio_characteristic_buffer_type; + bleio_characteristic_buffer_obj_t *self = + mp_obj_malloc(bleio_characteristic_buffer_obj_t, &bleio_characteristic_buffer_type); common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer_size); diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c index 9ebe95432e537..813ef8f9fe56e 100644 --- a/shared-bindings/_bleio/Descriptor.c +++ b/shared-bindings/_bleio/Descriptor.c @@ -122,8 +122,7 @@ STATIC mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o mp_raise_ValueError(translate("initial_value length is wrong")); } - bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t); - descriptor->base.type = &bleio_descriptor_type; + bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); // Range checking on max_length arg is done by the common_hal layer, because // it may vary depending on underlying BLE implementation. diff --git a/shared-bindings/_bleio/PacketBuffer.c b/shared-bindings/_bleio/PacketBuffer.c index 0ce74beff401b..2c03a6855e271 100644 --- a/shared-bindings/_bleio/PacketBuffer.c +++ b/shared-bindings/_bleio/PacketBuffer.c @@ -85,8 +85,7 @@ STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n max_packet_size = mp_obj_get_int(args[ARG_max_packet_size].u_obj); } - bleio_packet_buffer_obj_t *self = m_new_obj(bleio_packet_buffer_obj_t); - self->base.type = &bleio_packet_buffer_type; + bleio_packet_buffer_obj_t *self = mp_obj_malloc(bleio_packet_buffer_obj_t, &bleio_packet_buffer_type); common_hal_bleio_packet_buffer_construct(self, characteristic, buffer_size, max_packet_size); diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c index 7b357882f0281..f107b068e09e6 100644 --- a/shared-bindings/_bleio/Service.c +++ b/shared-bindings/_bleio/Service.c @@ -61,8 +61,7 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, const bool is_secondary = args[ARG_secondary].u_bool; - bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t); - service->base.type = &bleio_service_type; + bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); common_hal_bleio_service_construct(service, uuid, is_secondary); diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c index 922b1ac5fbf8b..b7fc05fbc6652 100644 --- a/shared-bindings/_bleio/UUID.c +++ b/shared-bindings/_bleio/UUID.c @@ -53,8 +53,7 @@ STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); - bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); - self->base.type = type; + bleio_uuid_obj_t *self = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); const mp_obj_t value = all_args[0]; uint8_t uuid128[16]; diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c index f34d3af5c52fe..ab41f8ff6fbec 100644 --- a/shared-bindings/_bleio/__init__.c +++ b/shared-bindings/_bleio/__init__.c @@ -68,7 +68,7 @@ MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception) NORETURN void mp_raise_bleio_BluetoothError(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_BluetoothError, fmt, argptr); va_end(argptr); nlr_raise(exception); @@ -93,7 +93,7 @@ NORETURN void mp_raise_bleio_RoleError(const compressed_string_t *msg) { MP_DEFINE_BLEIO_EXCEPTION(SecurityError, bleio_BluetoothError) NORETURN void mp_raise_bleio_SecurityError(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_SecurityError, fmt, argptr); va_end(argptr); nlr_raise(exception); @@ -203,4 +203,4 @@ const mp_obj_module_t bleio_module = { .globals = (mp_obj_dict_t *)&bleio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR__bleio, bleio_module, CIRCUITPY_BLEIO); +MP_REGISTER_MODULE(MP_QSTR__bleio, bleio_module); diff --git a/shared-bindings/_eve/__init__.c b/shared-bindings/_eve/__init__.c index 5975ee1ca177b..203a9cbfd23cf 100644 --- a/shared-bindings/_eve/__init__.c +++ b/shared-bindings/_eve/__init__.c @@ -1058,8 +1058,7 @@ STATIC MP_DEFINE_CONST_DICT(_EVE_locals_dict, _EVE_locals_dict_table); STATIC mp_obj_t _EVE_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // mp_arg_check_num(n_args, kw_args, 1, 1, false); - mp_obj__EVE_t *o = m_new_obj(mp_obj__EVE_t); - o->base.type = &_EVE_type; + mp_obj__EVE_t *o = mp_obj_malloc(mp_obj__EVE_t, &_EVE_type); o->_eve.n = 0; o->_eve.vscale = 16; return MP_OBJ_FROM_PTR(o); @@ -1084,4 +1083,4 @@ const mp_obj_module_t _eve_module = { .globals = (mp_obj_dict_t *)&mp_module__eve_globals, }; -MP_REGISTER_MODULE(MP_QSTR__eve, _eve_module, CIRCUITPY__EVE); +MP_REGISTER_MODULE(MP_QSTR__eve, _eve_module); diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c index 1a4356c71941b..229fb24381951 100644 --- a/shared-bindings/_pew/PewPew.c +++ b/shared-bindings/_pew/PewPew.c @@ -110,9 +110,7 @@ STATIC mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, size_t pew_obj_t *pew = MP_STATE_VM(pew_singleton); if (!pew) { - pew = m_new_obj(pew_obj_t); - pew->base.type = &pewpew_type; - pew = gc_make_long_lived(pew); + pew = mp_obj_malloc(pew_obj_t, &pewpew_type); MP_STATE_VM(pew_singleton) = pew; } diff --git a/shared-bindings/_pew/__init__.c b/shared-bindings/_pew/__init__.c index 13b9715bbd44c..435f50151a47a 100644 --- a/shared-bindings/_pew/__init__.c +++ b/shared-bindings/_pew/__init__.c @@ -62,5 +62,3 @@ const mp_obj_module_t pew_module = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *)&pew_module_globals, }; - -MP_REGISTER_MODULE(MP_QSTR__pew, pew_module, CIRCUITPY_PEW); diff --git a/shared-bindings/_pixelmap/PixelMap.c b/shared-bindings/_pixelmap/PixelMap.c index 94fa4d5c96168..5de918bbbebd6 100644 --- a/shared-bindings/_pixelmap/PixelMap.c +++ b/shared-bindings/_pixelmap/PixelMap.c @@ -87,8 +87,7 @@ STATIC mp_obj_t pixelmap_pixelmap_make_new(const mp_obj_type_t *type, size_t n_a } } - pixelmap_pixelmap_obj_t *self = m_new_obj(pixelmap_pixelmap_obj_t); - self->base.type = &pixelmap_pixelmap_type; + pixelmap_pixelmap_obj_t *self = mp_obj_malloc(pixelmap_pixelmap_obj_t, &pixelmap_pixelmap_type); shared_module_pixelmap_pixelmap_construct(self, pixelbuf, indices); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/_pixelmap/__init__.c b/shared-bindings/_pixelmap/__init__.c index 13a09d69d209f..9c71c5498ab37 100644 --- a/shared-bindings/_pixelmap/__init__.c +++ b/shared-bindings/_pixelmap/__init__.c @@ -59,4 +59,4 @@ const mp_obj_module_t pixelmap_module = { .globals = (mp_obj_dict_t *)&pixelmap_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR__pixelmap, pixelmap_module, CIRCUITPY_PIXELMAP); +MP_REGISTER_MODULE(MP_QSTR__pixelmap, pixelmap_module); diff --git a/shared-bindings/_stage/Layer.c b/shared-bindings/_stage/Layer.c index 81d76321f0b05..a5dd130dac76c 100644 --- a/shared-bindings/_stage/Layer.c +++ b/shared-bindings/_stage/Layer.c @@ -58,8 +58,7 @@ STATIC mp_obj_t layer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 4, 5, false); - layer_obj_t *self = m_new_obj(layer_obj_t); - self->base.type = type; + layer_obj_t *self = mp_obj_malloc(layer_obj_t, type); self->width = mp_obj_get_int(args[0]); self->height = mp_obj_get_int(args[1]); diff --git a/shared-bindings/_stage/Text.c b/shared-bindings/_stage/Text.c index c735669861b34..0c54f123d7cbb 100644 --- a/shared-bindings/_stage/Text.c +++ b/shared-bindings/_stage/Text.c @@ -58,8 +58,7 @@ STATIC mp_obj_t text_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 5, 5, false); - text_obj_t *self = m_new_obj(text_obj_t); - self->base.type = type; + text_obj_t *self = mp_obj_malloc(text_obj_t, type); self->width = mp_obj_get_int(args[0]); self->height = mp_obj_get_int(args[1]); diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index b2542f9df4ae5..46ae93f4baf3a 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -118,4 +118,4 @@ const mp_obj_module_t stage_module = { .globals = (mp_obj_dict_t *)&stage_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR__stage, stage_module, CIRCUITPY_STAGE); +MP_REGISTER_MODULE(MP_QSTR__stage, stage_module); diff --git a/shared-bindings/adafruit_bus_device/__init__.c b/shared-bindings/adafruit_bus_device/__init__.c index 410c6fb2f2f89..13993b18fff8f 100644 --- a/shared-bindings/adafruit_bus_device/__init__.c +++ b/shared-bindings/adafruit_bus_device/__init__.c @@ -76,6 +76,6 @@ const mp_obj_module_t adafruit_bus_device_module = { .globals = (mp_obj_dict_t *)&adafruit_bus_device_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_adafruit_bus_device, adafruit_bus_device_module, CIRCUITPY_BUSDEVICE); -MP_REGISTER_MODULE(MP_QSTR_adafruit_bus_device_dot_i2c_device, adafruit_bus_device_i2c_device_module, CIRCUITPY_BUSDEVICE); -MP_REGISTER_MODULE(MP_QSTR_adafruit_bus_device_dot_spi_device, adafruit_bus_device_spi_device_module, CIRCUITPY_BUSDEVICE); +MP_REGISTER_MODULE(MP_QSTR_adafruit_bus_device, adafruit_bus_device_module); +MP_REGISTER_MODULE(MP_QSTR_adafruit_bus_device_dot_i2c_device, adafruit_bus_device_i2c_device_module); +MP_REGISTER_MODULE(MP_QSTR_adafruit_bus_device_dot_spi_device, adafruit_bus_device_spi_device_module); diff --git a/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c index a77179c88663b..7dd5e09868c80 100644 --- a/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c +++ b/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c @@ -66,8 +66,8 @@ //| """ //| ... STATIC mp_obj_t adafruit_bus_device_i2cdevice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - adafruit_bus_device_i2cdevice_obj_t *self = m_new_obj(adafruit_bus_device_i2cdevice_obj_t); - self->base.type = &adafruit_bus_device_i2cdevice_type; + adafruit_bus_device_i2cdevice_obj_t *self = + mp_obj_malloc(adafruit_bus_device_i2cdevice_obj_t, &adafruit_bus_device_i2cdevice_type); enum { ARG_i2c, ARG_device_address, ARG_probe }; static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c index 13b57477e4d5f..47f93f323090f 100644 --- a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +++ b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c @@ -79,8 +79,8 @@ //| spi.write(bytes_read)""" //| ... STATIC mp_obj_t adafruit_bus_device_spidevice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - adafruit_bus_device_spidevice_obj_t *self = m_new_obj(adafruit_bus_device_spidevice_obj_t); - self->base.type = &adafruit_bus_device_spidevice_type; + adafruit_bus_device_spidevice_obj_t *self = + mp_obj_malloc(adafruit_bus_device_spidevice_obj_t, &adafruit_bus_device_spidevice_type); enum { ARG_spi, ARG_chip_select, ARG_cs_active_value, ARG_baudrate, ARG_polarity, ARG_phase, ARG_extra_clocks }; static const mp_arg_t allowed_args[] = { { MP_QSTR_spi, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/adafruit_pixelbuf/PixelBuf.c b/shared-bindings/adafruit_pixelbuf/PixelBuf.c index 2848a02c62465..d259b57dbbb19 100644 --- a/shared-bindings/adafruit_pixelbuf/PixelBuf.c +++ b/shared-bindings/adafruit_pixelbuf/PixelBuf.c @@ -120,8 +120,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_a } // Validation complete, allocate and populate object. - pixelbuf_pixelbuf_obj_t *self = m_new_obj(pixelbuf_pixelbuf_obj_t); - self->base.type = &pixelbuf_pixelbuf_type; + pixelbuf_pixelbuf_obj_t *self = mp_obj_malloc(pixelbuf_pixelbuf_obj_t, &pixelbuf_pixelbuf_type); common_hal_adafruit_pixelbuf_pixelbuf_construct(self, args[ARG_size].u_int, &byteorder_details, brightness, args[ARG_auto_write].u_bool, header_bufinfo.buf, header_bufinfo.len, trailer_bufinfo.buf, trailer_bufinfo.len); diff --git a/shared-bindings/adafruit_pixelbuf/__init__.c b/shared-bindings/adafruit_pixelbuf/__init__.c index fd2915ee0a209..bb741e3da608f 100644 --- a/shared-bindings/adafruit_pixelbuf/__init__.c +++ b/shared-bindings/adafruit_pixelbuf/__init__.c @@ -62,4 +62,4 @@ const mp_obj_module_t pixelbuf_module = { .globals = (mp_obj_dict_t *)&pixelbuf_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_adafruit_pixelbuf, pixelbuf_module, CIRCUITPY_PIXELBUF); +MP_REGISTER_MODULE(MP_QSTR_adafruit_pixelbuf, pixelbuf_module); diff --git a/shared-bindings/aesio/__init__.c b/shared-bindings/aesio/__init__.c index f3e1d7dd17853..314ac847b6e7e 100644 --- a/shared-bindings/aesio/__init__.c +++ b/shared-bindings/aesio/__init__.c @@ -68,4 +68,4 @@ const mp_obj_module_t aesio_module = { .globals = (mp_obj_dict_t *)&aesio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_aesio, aesio_module, CIRCUITPY_AESIO); +MP_REGISTER_MODULE(MP_QSTR_aesio, aesio_module); diff --git a/shared-bindings/aesio/aes.c b/shared-bindings/aesio/aes.c index 7ab895a1bd2b5..7a6a2f47ede83 100644 --- a/shared-bindings/aesio/aes.c +++ b/shared-bindings/aesio/aes.c @@ -47,8 +47,7 @@ STATIC mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - aesio_aes_obj_t *self = m_new_obj(aesio_aes_obj_t); - self->base.type = &aesio_aes_type; + aesio_aes_obj_t *self = mp_obj_malloc(aesio_aes_obj_t, &aesio_aes_type); enum { ARG_key, ARG_mode, ARG_IV, ARG_counter, ARG_segment_size }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 94879e14d417b..7f927df016d5f 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -312,4 +312,4 @@ MP_WEAK void common_hal_alarm_pretending_deep_sleep(void) { port_idle_until_interrupt(); } -MP_REGISTER_MODULE(MP_QSTR_alarm, alarm_module, CIRCUITPY_ALARM); +MP_REGISTER_MODULE(MP_QSTR_alarm, alarm_module); diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index c75061b77a68f..b0e21771c5935 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -62,8 +62,7 @@ //| """ //| ... STATIC mp_obj_t alarm_pin_pinalarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, size_t n_kw, const mp_obj_t *all_args) { - alarm_pin_pinalarm_obj_t *self = m_new_obj(alarm_pin_pinalarm_obj_t); - self->base.type = &alarm_pin_pinalarm_type; + alarm_pin_pinalarm_obj_t *self = mp_obj_malloc(alarm_pin_pinalarm_obj_t, &alarm_pin_pinalarm_type); enum { ARG_pin, ARG_value, ARG_edge, ARG_pull }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index 86c96de1d45d4..aed14613eae66 100644 --- a/shared-bindings/alarm/time/TimeAlarm.c +++ b/shared-bindings/alarm/time/TimeAlarm.c @@ -61,8 +61,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { //| ... STATIC mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - alarm_time_timealarm_obj_t *self = m_new_obj(alarm_time_timealarm_obj_t); - self->base.type = &alarm_time_timealarm_type; + alarm_time_timealarm_obj_t *self = mp_obj_malloc(alarm_time_timealarm_obj_t, &alarm_time_timealarm_type); enum { ARG_monotonic_time, ARG_epoch_time }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/alarm/touch/TouchAlarm.c b/shared-bindings/alarm/touch/TouchAlarm.c index 20612cb106d83..71fcb67a4f17f 100644 --- a/shared-bindings/alarm/touch/TouchAlarm.c +++ b/shared-bindings/alarm/touch/TouchAlarm.c @@ -45,8 +45,7 @@ //| ... STATIC mp_obj_t alarm_touch_touchalarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - alarm_touch_touchalarm_obj_t *self = m_new_obj(alarm_touch_touchalarm_obj_t); - self->base.type = &alarm_touch_touchalarm_type; + alarm_touch_touchalarm_obj_t *self = mp_obj_malloc(alarm_touch_touchalarm_obj_t, &alarm_touch_touchalarm_type); enum { ARG_pin }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/analogbufio/__init__.c b/shared-bindings/analogbufio/__init__.c index 749f1aec091fd..552fc56b2575f 100644 --- a/shared-bindings/analogbufio/__init__.c +++ b/shared-bindings/analogbufio/__init__.c @@ -59,4 +59,4 @@ const mp_obj_module_t analogbufio_module = { .globals = (mp_obj_dict_t *)&analogbufio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_analogbufio, analogbufio_module, CIRCUITPY_ANALOGBUFIO); +MP_REGISTER_MODULE(MP_QSTR_analogbufio, analogbufio_module); diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index 3b71f688c8091..faf085905e1d5 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -65,8 +65,7 @@ STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, // 1st argument is the pin const mcu_pin_obj_t *pin = common_hal_analogio_analogin_validate_pin(args[0]); - analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t); - self->base.type = &analogio_analogin_type; + analogio_analogin_obj_t *self = mp_obj_malloc(analogio_analogin_obj_t, &analogio_analogin_type); common_hal_analogio_analogin_construct(self, pin); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index 6b10d37571939..36a6532b7cc1e 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -63,8 +63,7 @@ STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0], MP_QSTR_pin); - analogio_analogout_obj_t *self = m_new_obj(analogio_analogout_obj_t); - self->base.type = &analogio_analogout_type; + analogio_analogout_obj_t *self = mp_obj_malloc(analogio_analogout_obj_t, &analogio_analogout_type); common_hal_analogio_analogout_construct(self, pin); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/analogio/__init__.c b/shared-bindings/analogio/__init__.c index 2e7ccf7115fe1..e6bd2f1f4d82f 100644 --- a/shared-bindings/analogio/__init__.c +++ b/shared-bindings/analogio/__init__.c @@ -79,4 +79,4 @@ const mp_obj_module_t analogio_module = { .globals = (mp_obj_dict_t *)&analogio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_analogio, analogio_module, CIRCUITPY_ANALOGIO); +MP_REGISTER_MODULE(MP_QSTR_analogio, analogio_module); diff --git a/shared-bindings/atexit/__init__.c b/shared-bindings/atexit/__init__.c index 9a91e0bc8020f..b3fe1b6c014b2 100644 --- a/shared-bindings/atexit/__init__.c +++ b/shared-bindings/atexit/__init__.c @@ -93,4 +93,4 @@ const mp_obj_module_t atexit_module = { .globals = (mp_obj_dict_t *)&atexit_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_atexit, atexit_module, CIRCUITPY_ATEXIT); +MP_REGISTER_MODULE(MP_QSTR_atexit, atexit_module); diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 1f0e50029203b..f5105b367a356 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -102,7 +102,7 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar { MP_QSTR_data_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_sample_rate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16000} }, { MP_QSTR_bit_depth, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, - { MP_QSTR_mono, MP_ARG_KW_ONLY | MP_ARG_BOOL,{.u_bool = true} }, + { MP_QSTR_mono, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, { MP_QSTR_oversample, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, { MP_QSTR_startup_delay, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, }; @@ -116,8 +116,7 @@ STATIC mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj, MP_QSTR_data_pin); // create PDMIn object from the given pin - audiobusio_pdmin_obj_t *self = m_new_obj(audiobusio_pdmin_obj_t); - self->base.type = &audiobusio_pdmin_type; + audiobusio_pdmin_obj_t *self = mp_obj_malloc(audiobusio_pdmin_obj_t, &audiobusio_pdmin_type); uint32_t sample_rate = args[ARG_sample_rate].u_int; uint8_t bit_depth = args[ARG_bit_depth].u_int; diff --git a/shared-bindings/audiobusio/__init__.c b/shared-bindings/audiobusio/__init__.c index 937028ee1f0fb..a7ae705170b41 100644 --- a/shared-bindings/audiobusio/__init__.c +++ b/shared-bindings/audiobusio/__init__.c @@ -58,4 +58,4 @@ const mp_obj_module_t audiobusio_module = { .globals = (mp_obj_dict_t *)&audiobusio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_audiobusio, audiobusio_module, CIRCUITPY_AUDIOBUSIO); +MP_REGISTER_MODULE(MP_QSTR_audiobusio, audiobusio_module); diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c index 39992f87c1792..58ec83fe3520b 100644 --- a/shared-bindings/audiocore/RawSample.c +++ b/shared-bindings/audiocore/RawSample.c @@ -80,8 +80,7 @@ STATIC mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - audioio_rawsample_obj_t *self = m_new_obj(audioio_rawsample_obj_t); - self->base.type = &audioio_rawsample_type; + audioio_rawsample_obj_t *self = mp_obj_malloc(audioio_rawsample_obj_t, &audioio_rawsample_type); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); uint8_t bytes_per_sample = 1; diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index 3a13db72a02ed..aa503210402f7 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -79,8 +79,7 @@ STATIC mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_ar arg = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), arg, MP_ROM_QSTR(MP_QSTR_rb)); } - audioio_wavefile_obj_t *self = m_new_obj(audioio_wavefile_obj_t); - self->base.type = &audioio_wavefile_type; + audioio_wavefile_obj_t *self = mp_obj_malloc(audioio_wavefile_obj_t, &audioio_wavefile_type); if (!mp_obj_is_type(arg, &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c index 3ecd7391b6578..7a39a55366a0c 100644 --- a/shared-bindings/audiocore/__init__.c +++ b/shared-bindings/audiocore/__init__.c @@ -54,7 +54,7 @@ STATIC mp_obj_t audiocore_get_buffer(mp_obj_t sample_in) { uint8_t bits_per_sample = audiosample_bits_per_sample(sample_in); audiosample_get_buffer_structure(sample_in, false, &single_buffer, &samples_signed, &max_buffer_length, &spacing); // copies the data because the gc semantics of get_buffer are unclear - void *result_buf = gc_alloc(buffer_length, 0, false); + void *result_buf = m_malloc(buffer_length); memcpy(result_buf, buffer, buffer_length); char typecode = (bits_per_sample == 8 && samples_signed) ? 'b' : @@ -112,4 +112,4 @@ const mp_obj_module_t audiocore_module = { .globals = (mp_obj_dict_t *)&audiocore_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_audiocore, audiocore_module, CIRCUITPY_AUDIOCORE); +MP_REGISTER_MODULE(MP_QSTR_audiocore, audiocore_module); diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 7909176114c93..c66f109f9a3df 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -111,8 +111,7 @@ STATIC mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj, MP_QSTR_right_channel); // create AudioOut object from the given pin - audioio_audioout_obj_t *self = m_new_obj(audioio_audioout_obj_t); - self->base.type = &audioio_audioout_type; + audioio_audioout_obj_t *self = mp_obj_malloc(audioio_audioout_obj_t, &audioio_audioout_type); common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c index b76b534a7da2a..89778d8f82e48 100644 --- a/shared-bindings/audioio/__init__.c +++ b/shared-bindings/audioio/__init__.c @@ -65,4 +65,4 @@ const mp_obj_module_t audioio_module = { .globals = (mp_obj_dict_t *)&audioio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_audioio, audioio_module, CIRCUITPY_AUDIOIO); +MP_REGISTER_MODULE(MP_QSTR_audioio, audioio_module); diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c index 83fcc06712386..6ddc5c3641de2 100644 --- a/shared-bindings/audiomixer/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -103,8 +103,8 @@ STATIC mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_ar if (bits_per_sample != 8 && bits_per_sample != 16) { mp_raise_ValueError(translate("bits_per_sample must be 8 or 16")); } - audiomixer_mixer_obj_t *self = m_new_obj_var(audiomixer_mixer_obj_t, mp_obj_t, voice_count); - self->base.type = &audiomixer_mixer_type; + audiomixer_mixer_obj_t *self = + mp_obj_malloc_var(audiomixer_mixer_obj_t, mp_obj_t, voice_count, &audiomixer_mixer_type); common_hal_audiomixer_mixer_construct(self, voice_count, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); for (int v = 0; v < voice_count; v++) { diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index 1d6cd7f39a567..74b9c6745d22a 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -46,8 +46,7 @@ // TODO: support mono or stereo voices STATIC mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 0, 0, false); - audiomixer_mixervoice_obj_t *self = m_new_obj(audiomixer_mixervoice_obj_t); - self->base.type = &audiomixer_mixervoice_type; + audiomixer_mixervoice_obj_t *self = mp_obj_malloc(audiomixer_mixervoice_obj_t, &audiomixer_mixervoice_type); common_hal_audiomixer_mixervoice_construct(self); diff --git a/shared-bindings/audiomixer/__init__.c b/shared-bindings/audiomixer/__init__.c index 4c8068172bbe1..552cc55e0c127 100644 --- a/shared-bindings/audiomixer/__init__.c +++ b/shared-bindings/audiomixer/__init__.c @@ -45,4 +45,4 @@ const mp_obj_module_t audiomixer_module = { .globals = (mp_obj_dict_t *)&audiomixer_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_audiomixer, audiomixer_module, CIRCUITPY_AUDIOMIXER); +MP_REGISTER_MODULE(MP_QSTR_audiomixer, audiomixer_module); diff --git a/shared-bindings/audiomp3/MP3Decoder.c b/shared-bindings/audiomp3/MP3Decoder.c index 68e78cb0d5956..ef5445a1de633 100644 --- a/shared-bindings/audiomp3/MP3Decoder.c +++ b/shared-bindings/audiomp3/MP3Decoder.c @@ -95,8 +95,7 @@ STATIC mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar arg = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), arg, MP_ROM_QSTR(MP_QSTR_rb)); } - audiomp3_mp3file_obj_t *self = m_new_obj(audiomp3_mp3file_obj_t); - self->base.type = &audiomp3_mp3file_type; + audiomp3_mp3file_obj_t *self = mp_obj_malloc(audiomp3_mp3file_obj_t, &audiomp3_mp3file_type); if (!mp_obj_is_type(arg, &mp_type_fileio)) { mp_raise_TypeError(translate("file must be a file opened in byte mode")); } diff --git a/shared-bindings/audiomp3/__init__.c b/shared-bindings/audiomp3/__init__.c index 9fe525dfe23c3..09a3d4f886062 100644 --- a/shared-bindings/audiomp3/__init__.c +++ b/shared-bindings/audiomp3/__init__.c @@ -50,4 +50,4 @@ const mp_obj_module_t audiomp3_module = { .globals = (mp_obj_dict_t *)&audiomp3_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_audiomp3, audiomp3_module, CIRCUITPY_AUDIOMP3); +MP_REGISTER_MODULE(MP_QSTR_audiomp3, audiomp3_module); diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c index f05fbfdfe92ce..ce35374618571 100644 --- a/shared-bindings/audiopwmio/PWMAudioOut.c +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -118,12 +118,9 @@ STATIC mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_ validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj, MP_QSTR_right_channel); // create AudioOut object from the given pin - // The object is made long-lived because many implementations keep - // a pointer to the object (e.g., for the interrupt handler), which - // will not work properly if the object is moved. It is created - // with a finaliser as some ports use these (rather than 'reset' functions) + // The object is created with a finaliser as some ports use these (rather than 'reset' functions) // to ensure resources are collected at interpreter shutdown. - audiopwmio_pwmaudioout_obj_t *self = m_new_ll_obj_with_finaliser(audiopwmio_pwmaudioout_obj_t); + audiopwmio_pwmaudioout_obj_t *self = m_new_obj_with_finaliser(audiopwmio_pwmaudioout_obj_t); self->base.type = &audiopwmio_pwmaudioout_type; common_hal_audiopwmio_pwmaudioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); diff --git a/shared-bindings/audiopwmio/__init__.c b/shared-bindings/audiopwmio/__init__.c index 441bca21327e8..f8d7c0e5cb5dd 100644 --- a/shared-bindings/audiopwmio/__init__.c +++ b/shared-bindings/audiopwmio/__init__.c @@ -57,4 +57,4 @@ const mp_obj_module_t audiopwmio_module = { .globals = (mp_obj_dict_t *)&audiopwmio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_audiopwmio, audiopwmio_module, CIRCUITPY_AUDIOPWMIO); +MP_REGISTER_MODULE(MP_QSTR_audiopwmio, audiopwmio_module); diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 9684b87df2ed3..390e1c0c98d2b 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -80,8 +80,7 @@ STATIC mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl); const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda); - bitbangio_i2c_obj_t *self = m_new_obj(bitbangio_i2c_obj_t); - self->base.type = &bitbangio_i2c_type; + bitbangio_i2c_obj_t *self = mp_obj_malloc(bitbangio_i2c_obj_t, &bitbangio_i2c_type); shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); return (mp_obj_t)self; } diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index cf4f34f0e48c1..2ec2220bef5db 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -89,8 +89,7 @@ STATIC mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj, MP_QSTR_mosi); const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj, MP_QSTR_miso); - bitbangio_spi_obj_t *self = m_new_obj(bitbangio_spi_obj_t); - self->base.type = &bitbangio_spi_type; + bitbangio_spi_obj_t *self = mp_obj_malloc(bitbangio_spi_obj_t, &bitbangio_spi_type); shared_module_bitbangio_spi_construct(self, clock, mosi, miso); return (mp_obj_t)self; } @@ -274,7 +273,7 @@ STATIC mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_write_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); diff --git a/shared-bindings/bitbangio/__init__.c b/shared-bindings/bitbangio/__init__.c index 1b13003e89172..99bf6d26a77cd 100644 --- a/shared-bindings/bitbangio/__init__.c +++ b/shared-bindings/bitbangio/__init__.c @@ -80,4 +80,4 @@ const mp_obj_module_t bitbangio_module = { .globals = (mp_obj_dict_t *)&bitbangio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_bitbangio, bitbangio_module, CIRCUITPY_BITBANGIO); +MP_REGISTER_MODULE(MP_QSTR_bitbangio, bitbangio_module); diff --git a/shared-bindings/bitmaptools/__init__.c b/shared-bindings/bitmaptools/__init__.c index befa1b298e373..a6fc785a680a2 100644 --- a/shared-bindings/bitmaptools/__init__.c +++ b/shared-bindings/bitmaptools/__init__.c @@ -1153,4 +1153,4 @@ const mp_obj_module_t bitmaptools_module = { .globals = (mp_obj_dict_t *)&bitmaptools_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_bitmaptools, bitmaptools_module, CIRCUITPY_BITMAPTOOLS); +MP_REGISTER_MODULE(MP_QSTR_bitmaptools, bitmaptools_module); diff --git a/shared-bindings/bitops/__init__.c b/shared-bindings/bitops/__init__.c index 3107b310dbd7d..48cf1df0d62de 100644 --- a/shared-bindings/bitops/__init__.c +++ b/shared-bindings/bitops/__init__.c @@ -99,4 +99,4 @@ const mp_obj_module_t bitops_module = { .globals = (mp_obj_dict_t *)&bitops_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_bitops, bitops_module, CIRCUITPY_BITOPS); +MP_REGISTER_MODULE(MP_QSTR_bitops, bitops_module); diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c index 99b99b37ea899..273ef7ff90ef8 100644 --- a/shared-bindings/board/__init__.c +++ b/shared-bindings/board/__init__.c @@ -119,4 +119,4 @@ const mp_obj_module_t board_module = { .globals = (mp_obj_dict_t *)&board_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_board, board_module, CIRCUITPY_BOARD); +MP_REGISTER_MODULE(MP_QSTR_board, board_module); diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 5cf52eaa1a1a7..14ec7093a54a9 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -68,8 +68,7 @@ //| """ //| ... STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); - self->base.type = &busio_i2c_type; + busio_i2c_obj_t *self = mp_obj_malloc(busio_i2c_obj_t, &busio_i2c_type); enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index ccdceb57607a5..9d843a75005e6 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -91,8 +91,7 @@ // TODO(tannewt): Support LSB SPI. STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BUSIO_SPI - busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); - self->base.type = &busio_spi_type; + busio_spi_obj_t *self = mp_obj_malloc(busio_spi_obj_t, &busio_spi_type); enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -319,7 +318,7 @@ STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_write_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, }; busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index a10dc8efad80a..314a012d01e0b 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -104,7 +104,7 @@ STATIC void validate_timeout(mp_float_t timeout) { STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BUSIO_UART enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size, - ARG_rts, ARG_cts, ARG_rs485_dir,ARG_rs485_invert}; + ARG_rts, ARG_cts, ARG_rs485_dir, ARG_rs485_invert}; static const mp_arg_t allowed_args[] = { { MP_QSTR_tx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_rx, MP_ARG_OBJ, {.u_obj = mp_const_none} }, @@ -155,11 +155,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si const bool rs485_invert = args[ARG_rs485_invert].u_bool; - // Always initially allocate the UART object within the long-lived heap. - // This is needed to avoid crashes with certain UART implementations which - // cannot accommodate being moved after creation. (See - // https://github.com/adafruit/circuitpython/issues/1056) - busio_uart_obj_t *self = m_new_ll_obj_with_finaliser(busio_uart_obj_t); + busio_uart_obj_t *self = m_new_obj_with_finaliser(busio_uart_obj_t); self->base.type = &busio_uart_type; common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c index 4d62c8333e4c6..5d6b60ac3f0f9 100644 --- a/shared-bindings/busio/__init__.c +++ b/shared-bindings/busio/__init__.c @@ -93,4 +93,4 @@ const mp_obj_module_t busio_module = { .globals = (mp_obj_dict_t *)&busio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_busio, busio_module, CIRCUITPY_BUSIO); +MP_REGISTER_MODULE(MP_QSTR_busio, busio_module); diff --git a/shared-bindings/camera/Camera.c b/shared-bindings/camera/Camera.c index 4f6023c9fdb19..eea22a0d8171f 100644 --- a/shared-bindings/camera/Camera.c +++ b/shared-bindings/camera/Camera.c @@ -61,8 +61,7 @@ //| """Initialize camera.""" //| ... STATIC mp_obj_t camera_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - camera_obj_t *self = m_new_obj(camera_obj_t); - self->base.type = &camera_type; + camera_obj_t *self = mp_obj_malloc(camera_obj_t, &camera_type); // No arguments mp_arg_check_num(n_args, n_kw, 0, 0, false); diff --git a/shared-bindings/camera/__init__.c b/shared-bindings/camera/__init__.c index e4ee263f58798..a2b15933c4487 100644 --- a/shared-bindings/camera/__init__.c +++ b/shared-bindings/camera/__init__.c @@ -48,4 +48,4 @@ const mp_obj_module_t camera_module = { .globals = (mp_obj_dict_t *)&camera_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_camera, camera_module, CIRCUITPY_CAMERA); +MP_REGISTER_MODULE(MP_QSTR_camera, camera_module); diff --git a/shared-bindings/canio/CAN.c b/shared-bindings/canio/CAN.c index bce581f501280..912255adf46e9 100644 --- a/shared-bindings/canio/CAN.c +++ b/shared-bindings/canio/CAN.c @@ -83,8 +83,7 @@ STATIC mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_raise_ValueError(translate("tx and rx cannot both be None")); } - canio_can_obj_t *self = m_new_obj(canio_can_obj_t); - self->base.type = &canio_can_type; + canio_can_obj_t *self = mp_obj_malloc(canio_can_obj_t, &canio_can_type); common_hal_canio_can_construct(self, tx_pin, rx_pin, args[ARG_baudrate].u_int, args[ARG_loopback].u_bool, args[ARG_silent].u_bool); common_hal_canio_can_auto_restart_set(self, args[ARG_auto_restart].u_bool); diff --git a/shared-bindings/canio/Match.c b/shared-bindings/canio/Match.c index 06729f9c54c3b..1a9cd34916398 100644 --- a/shared-bindings/canio/Match.c +++ b/shared-bindings/canio/Match.c @@ -64,8 +64,7 @@ STATIC mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, s mp_raise_ValueError_varg(translate("%q out of range"), MP_QSTR_mask); } - canio_match_obj_t *self = m_new_obj(canio_match_obj_t); - self->base.type = &canio_match_type; + canio_match_obj_t *self = mp_obj_malloc(canio_match_obj_t, &canio_match_type); common_hal_canio_match_construct(self, id, mask, args[ARG_extended].u_bool); return self; } diff --git a/shared-bindings/canio/Message.c b/shared-bindings/canio/Message.c index c3857256bd2cf..432b10b4e883d 100644 --- a/shared-bindings/canio/Message.c +++ b/shared-bindings/canio/Message.c @@ -58,8 +58,7 @@ STATIC mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_validate_length_range(data.len, 0, 8, MP_QSTR_data); - canio_message_obj_t *self = m_new_obj(canio_message_obj_t); - self->base.type = &canio_message_type; + canio_message_obj_t *self = mp_obj_malloc(canio_message_obj_t, &canio_message_type); common_hal_canio_message_construct(self, args[ARG_id].u_int, data.buf, data.len, args[ARG_extended].u_bool); return self; } diff --git a/shared-bindings/canio/RemoteTransmissionRequest.c b/shared-bindings/canio/RemoteTransmissionRequest.c index 1efc401909bb4..4b55bf2e75058 100644 --- a/shared-bindings/canio/RemoteTransmissionRequest.c +++ b/shared-bindings/canio/RemoteTransmissionRequest.c @@ -58,8 +58,8 @@ STATIC mp_obj_t canio_remote_transmission_request_make_new(const mp_obj_type_t * mp_raise_ValueError(translate("RemoteTransmissionRequests limited to 8 bytes")); } - canio_remote_transmission_request_obj_t *self = m_new_obj(canio_remote_transmission_request_obj_t); - self->base.type = &canio_remote_transmission_request_type; + canio_remote_transmission_request_obj_t *self = + mp_obj_malloc(canio_remote_transmission_request_obj_t, &canio_remote_transmission_request_type); common_hal_canio_remote_transmission_request_construct(self, args[ARG_id].u_int, length, args[ARG_extended].u_bool); return self; } diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index ecef7ebde6db8..f5de9af547c1d 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -128,4 +128,4 @@ const mp_obj_module_t canio_module = { .globals = (mp_obj_dict_t *)&canio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_canio, canio_module, CIRCUITPY_CANIO); +MP_REGISTER_MODULE(MP_QSTR_canio, canio_module); diff --git a/shared-bindings/countio/Counter.c b/shared-bindings/countio/Counter.c index 89b205e7630a2..2b646a83a7c3c 100644 --- a/shared-bindings/countio/Counter.c +++ b/shared-bindings/countio/Counter.c @@ -60,8 +60,7 @@ STATIC mp_obj_t countio_counter_make_new(const mp_obj_type_t *type, size_t n_arg const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); const countio_edge_t edge = validate_edge(args[ARG_edge].u_obj, MP_QSTR_edge); const digitalio_pull_t pull = validate_pull(args[ARG_pull].u_obj, MP_QSTR_pull); - // Make long-lived because some implementations use a pointer to the object as interrupt-handler data. - countio_counter_obj_t *self = m_new_ll_obj_with_finaliser(countio_counter_obj_t); + countio_counter_obj_t *self = m_new_obj_with_finaliser(countio_counter_obj_t); self->base.type = &countio_counter_type; common_hal_countio_counter_construct(self, pin, edge, pull); diff --git a/shared-bindings/countio/__init__.c b/shared-bindings/countio/__init__.c index 0d412cc17f728..c8327c9a575c9 100644 --- a/shared-bindings/countio/__init__.c +++ b/shared-bindings/countio/__init__.c @@ -35,4 +35,4 @@ const mp_obj_module_t countio_module = { .globals = (mp_obj_dict_t *)&countio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_countio, countio_module, CIRCUITPY_COUNTIO); +MP_REGISTER_MODULE(MP_QSTR_countio, countio_module); diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index c0195115fa66f..832f16558ac16 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -90,8 +90,7 @@ STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); - digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t); - self->base.type = &digitalio_digitalinout_type; + digitalio_digitalinout_obj_t *self = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); const mcu_pin_obj_t *pin = common_hal_digitalio_validate_pin(args[0]); common_hal_digitalio_digitalinout_construct(self, pin); diff --git a/shared-bindings/digitalio/__init__.c b/shared-bindings/digitalio/__init__.c index 9a9db698167a6..938b7df754ab3 100644 --- a/shared-bindings/digitalio/__init__.c +++ b/shared-bindings/digitalio/__init__.c @@ -97,4 +97,4 @@ const mp_obj_module_t digitalio_module = { .globals = (mp_obj_dict_t *)&digitalio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_digitalio, digitalio_module, CIRCUITPY_DIGITALIO); +MP_REGISTER_MODULE(MP_QSTR_digitalio, digitalio_module); diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 17a4b4c87f5c1..7a314f00987f8 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -75,8 +75,7 @@ STATIC mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_ar } } - displayio_bitmap_t *self = m_new_obj(displayio_bitmap_t); - self->base.type = &displayio_bitmap_type; + displayio_bitmap_t *self = mp_obj_malloc(displayio_bitmap_t, &displayio_bitmap_type); common_hal_displayio_bitmap_construct(self, width, height, bits); return MP_OBJ_FROM_PTR(self); @@ -208,7 +207,7 @@ STATIC mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - mp_uint_t value = (mp_uint_t)mp_arg_validate_int_range(mp_obj_get_int(value_obj), 0,(1u << common_hal_displayio_bitmap_get_bits_per_value(self)) - 1,MP_QSTR_value); + mp_uint_t value = (mp_uint_t)mp_arg_validate_int_range(mp_obj_get_int(value_obj), 0, (1u << common_hal_displayio_bitmap_get_bits_per_value(self)) - 1, MP_QSTR_value); common_hal_displayio_bitmap_fill(self, value); return mp_const_none; diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c index 06de5a4b0961a..0ec78779ee06e 100644 --- a/shared-bindings/displayio/ColorConverter.c +++ b/shared-bindings/displayio/ColorConverter.c @@ -58,8 +58,7 @@ STATIC mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_colorconverter_t *self = m_new_obj(displayio_colorconverter_t); - self->base.type = &displayio_colorconverter_type; + displayio_colorconverter_t *self = mp_obj_malloc(displayio_colorconverter_t, &displayio_colorconverter_type); common_hal_displayio_colorconverter_construct(self, args[ARG_dither].u_bool, (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_input_colorspace].u_obj, MP_QSTR_input_colorspace)); diff --git a/shared-bindings/displayio/EPaperDisplay.c b/shared-bindings/displayio/EPaperDisplay.c index f4f97ff9712b6..cca8c919cc0b7 100644 --- a/shared-bindings/displayio/EPaperDisplay.c +++ b/shared-bindings/displayio/EPaperDisplay.c @@ -206,7 +206,7 @@ STATIC mp_obj_t displayio_epaperdisplay_make_new(const mp_obj_type_t *type, size size_t refresh_buf_len = 0; mp_int_t refresh_command; if (mp_obj_get_int_maybe(refresh_obj, &refresh_command)) { - uint8_t *command_buf = m_malloc(3, true); + uint8_t *command_buf = m_malloc(3); command_buf[0] = refresh_command; command_buf[1] = 0; command_buf[2] = 0; diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 279e1f161b6b2..0800f4c861f07 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -56,10 +56,9 @@ STATIC mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - mp_int_t scale = mp_arg_validate_int_range(args[ARG_scale].u_int, 1, 32767,MP_QSTR_scale); + mp_int_t scale = mp_arg_validate_int_range(args[ARG_scale].u_int, 1, 32767, MP_QSTR_scale); - displayio_group_t *self = m_new_obj(displayio_group_t); - self->base.type = &displayio_group_type; + displayio_group_t *self = mp_obj_malloc(displayio_group_t, &displayio_group_type); common_hal_displayio_group_construct(self, scale, args[ARG_x].u_int, args[ARG_y].u_int); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c index a53196ef05d96..d0dcba2339e14 100644 --- a/shared-bindings/displayio/OnDiskBitmap.c +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -89,8 +89,7 @@ STATIC mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_ mp_raise_TypeError(translate("file must be a file opened in byte mode")); } - displayio_ondiskbitmap_t *self = m_new_obj(displayio_ondiskbitmap_t); - self->base.type = &displayio_ondiskbitmap_type; + displayio_ondiskbitmap_t *self = mp_obj_malloc(displayio_ondiskbitmap_t, &displayio_ondiskbitmap_type); common_hal_displayio_ondiskbitmap_construct(self, MP_OBJ_TO_PTR(arg)); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index 0c44ed0f6094a..abe5e369dd53a 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -59,8 +59,7 @@ STATIC mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_palette_t *self = m_new_obj(displayio_palette_t); - self->base.type = &displayio_palette_type; + displayio_palette_t *self = mp_obj_malloc(displayio_palette_t, &displayio_palette_type); common_hal_displayio_palette_construct(self, mp_arg_validate_int_range(args[ARG_color_count].u_int, 1, 32767, MP_QSTR_color_count), args[ARG_dither].u_bool); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/displayio/Shape.c b/shared-bindings/displayio/Shape.c index e7ed29cbad3ad..572ed216b84a6 100644 --- a/shared-bindings/displayio/Shape.c +++ b/shared-bindings/displayio/Shape.c @@ -62,8 +62,7 @@ STATIC mp_obj_t displayio_shape_make_new(const mp_obj_type_t *type, size_t n_arg mp_int_t width = mp_arg_validate_int_min(args[ARG_width].u_int, 1, MP_QSTR_width); mp_int_t height = mp_arg_validate_int_min(args[ARG_height].u_int, 1, MP_QSTR_height); - displayio_shape_t *self = m_new_obj(displayio_shape_t); - self->base.type = &displayio_shape_type; + displayio_shape_t *self = mp_obj_malloc(displayio_shape_t, &displayio_shape_type); common_hal_displayio_shape_construct(self, width, height, diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index f2e16985c3f55..5d27580fdf893 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -139,8 +139,7 @@ STATIC mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_ int16_t x = args[ARG_x].u_int; int16_t y = args[ARG_y].u_int; - displayio_tilegrid_t *self = m_new_obj(displayio_tilegrid_t); - self->base.type = &displayio_tilegrid_type; + displayio_tilegrid_t *self = mp_obj_malloc(displayio_tilegrid_t, &displayio_tilegrid_type); common_hal_displayio_tilegrid_construct(self, native, bitmap_width / tile_width, bitmap_height / tile_height, pixel_shader, args[ARG_width].u_int, args[ARG_height].u_int, diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index 6b4dc6d8954da..e377a49dea662 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -109,4 +109,4 @@ const mp_obj_module_t displayio_module = { .globals = (mp_obj_dict_t *)&displayio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module, CIRCUITPY_DISPLAYIO); +MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module); diff --git a/shared-bindings/dualbank/__init__.c b/shared-bindings/dualbank/__init__.c index b77fb6d76b5ed..0bb095ddac640 100644 --- a/shared-bindings/dualbank/__init__.c +++ b/shared-bindings/dualbank/__init__.c @@ -141,4 +141,4 @@ const mp_obj_module_t dualbank_module = { .globals = (mp_obj_dict_t *)&dualbank_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_dualbank, dualbank_module, CIRCUITPY_DUALBANK); +MP_REGISTER_MODULE(MP_QSTR_dualbank, dualbank_module); diff --git a/shared-bindings/floppyio/__init__.c b/shared-bindings/floppyio/__init__.c index b114ab46dcd67..86c5813bdc9db 100644 --- a/shared-bindings/floppyio/__init__.c +++ b/shared-bindings/floppyio/__init__.c @@ -127,4 +127,4 @@ const mp_obj_module_t floppyio_module = { .globals = (mp_obj_dict_t *)&floppyio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_floppyio, floppyio_module, CIRCUITPY_FLOPPYIO); +MP_REGISTER_MODULE(MP_QSTR_floppyio, floppyio_module); diff --git a/shared-bindings/fontio/__init__.c b/shared-bindings/fontio/__init__.c index 24e1eb1e3b86e..d988ceda7f8ee 100644 --- a/shared-bindings/fontio/__init__.c +++ b/shared-bindings/fontio/__init__.c @@ -56,4 +56,4 @@ const mp_obj_module_t fontio_module = { .globals = (mp_obj_dict_t *)&fontio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_fontio, fontio_module, CIRCUITPY_FONTIO); +MP_REGISTER_MODULE(MP_QSTR_fontio, fontio_module); diff --git a/shared-bindings/framebufferio/__init__.c b/shared-bindings/framebufferio/__init__.c index 324442268e1d5..739c26f17134e 100644 --- a/shared-bindings/framebufferio/__init__.c +++ b/shared-bindings/framebufferio/__init__.c @@ -49,5 +49,5 @@ const mp_obj_module_t framebufferio_module = { .globals = (mp_obj_dict_t *)&framebufferio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_framebufferio, framebufferio_module, CIRCUITPY_FRAMEBUFFERIO); +MP_REGISTER_MODULE(MP_QSTR_framebufferio, framebufferio_module); #endif diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c index bf09196e3d51e..c3ce5e94a7235 100644 --- a/shared-bindings/frequencyio/FrequencyIn.c +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -73,8 +73,8 @@ STATIC mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); - frequencyio_frequencyin_obj_t *self = m_new_obj(frequencyio_frequencyin_obj_t); - self->base.type = &frequencyio_frequencyin_type; + frequencyio_frequencyin_obj_t *self = + mp_obj_malloc(frequencyio_frequencyin_obj_t, &frequencyio_frequencyin_type); enum { ARG_pin, ARG_capture_period }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/frequencyio/__init__.c b/shared-bindings/frequencyio/__init__.c index 18022c7f6e4de..80b60651de9a2 100644 --- a/shared-bindings/frequencyio/__init__.c +++ b/shared-bindings/frequencyio/__init__.c @@ -71,4 +71,4 @@ const mp_obj_module_t frequencyio_module = { .globals = (mp_obj_dict_t *)&frequencyio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_frequencyio, frequencyio_module, CIRCUITPY_FREQUENCYIO); +MP_REGISTER_MODULE(MP_QSTR_frequencyio, frequencyio_module); diff --git a/shared-bindings/getpass/__init__.c b/shared-bindings/getpass/__init__.c index 811d78e03dc8d..d6b65ec945d35 100644 --- a/shared-bindings/getpass/__init__.c +++ b/shared-bindings/getpass/__init__.c @@ -84,4 +84,4 @@ const mp_obj_module_t getpass_module = { .globals = (mp_obj_dict_t *)&getpass_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_getpass, getpass_module, CIRCUITPY_GETPASS); +MP_REGISTER_MODULE(MP_QSTR_getpass, getpass_module); diff --git a/shared-bindings/gifio/GifWriter.c b/shared-bindings/gifio/GifWriter.c index a0de52e2cc753..e28d48bb99d54 100644 --- a/shared-bindings/gifio/GifWriter.c +++ b/shared-bindings/gifio/GifWriter.c @@ -73,8 +73,7 @@ static mp_obj_t gifio_gifwriter_make_new(const mp_obj_type_t *type, size_t n_arg own_file = true; } - gifio_gifwriter_t *self = m_new_obj(gifio_gifwriter_t); - self->base.type = &gifio_gifwriter_type; + gifio_gifwriter_t *self = mp_obj_malloc(gifio_gifwriter_t, &gifio_gifwriter_type); shared_module_gifio_gifwriter_construct( self, file, diff --git a/shared-bindings/gifio/OnDiskGif.c b/shared-bindings/gifio/OnDiskGif.c index 8a7bba3a7fca6..840d58e410851 100644 --- a/shared-bindings/gifio/OnDiskGif.c +++ b/shared-bindings/gifio/OnDiskGif.c @@ -141,8 +141,7 @@ STATIC mp_obj_t gifio_ondiskgif_make_new(const mp_obj_type_t *type, size_t n_arg mp_raise_TypeError(translate("file must be a file opened in byte mode")); } - gifio_ondiskgif_t *self = m_new_obj(gifio_ondiskgif_t); - self->base.type = &gifio_ondiskgif_type; + gifio_ondiskgif_t *self = mp_obj_malloc(gifio_ondiskgif_t, &gifio_ondiskgif_type); common_hal_gifio_ondiskgif_construct(self, MP_OBJ_TO_PTR(filename), args[ARG_use_palette].u_bool); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/gifio/__init__.c b/shared-bindings/gifio/__init__.c index bfc87f0d99517..7691a6cedb67c 100644 --- a/shared-bindings/gifio/__init__.c +++ b/shared-bindings/gifio/__init__.c @@ -45,4 +45,4 @@ const mp_obj_module_t gifio_module = { .globals = (mp_obj_dict_t *)&gifio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_gifio, gifio_module, CIRCUITPY_GIFIO); +MP_REGISTER_MODULE(MP_QSTR_gifio, gifio_module); diff --git a/shared-bindings/gnss/GNSS.c b/shared-bindings/gnss/GNSS.c index d3c95477875e9..54b3f0b46cfb1 100644 --- a/shared-bindings/gnss/GNSS.c +++ b/shared-bindings/gnss/GNSS.c @@ -37,8 +37,7 @@ //| :param system: satellite system to use""" //| ... STATIC mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - gnss_obj_t *self = m_new_obj(gnss_obj_t); - self->base.type = &gnss_type; + gnss_obj_t *self = mp_obj_malloc(gnss_obj_t, &gnss_type); enum { ARG_system }; static const mp_arg_t allowed_args[] = { { MP_QSTR_system, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/gnss/__init__.c b/shared-bindings/gnss/__init__.c index 6029e1a54e24f..4409b0be1b360 100644 --- a/shared-bindings/gnss/__init__.c +++ b/shared-bindings/gnss/__init__.c @@ -29,4 +29,4 @@ const mp_obj_module_t gnss_module = { .globals = (mp_obj_dict_t *)&gnss_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_gnss, gnss_module, CIRCUITPY_GNSS); +MP_REGISTER_MODULE(MP_QSTR_gnss, gnss_module); diff --git a/shared-bindings/hashlib/__init__.c b/shared-bindings/hashlib/__init__.c index 424159f84ce1c..87f6df495af59 100644 --- a/shared-bindings/hashlib/__init__.c +++ b/shared-bindings/hashlib/__init__.c @@ -57,8 +57,7 @@ STATIC mp_obj_t hashlib_new(size_t n_args, const mp_obj_t *pos_args, mp_map_t *k const char *algorithm = mp_obj_str_get_str(args[ARG_name].u_obj); - hashlib_hash_obj_t *self = m_new_obj(hashlib_hash_obj_t); - self->base.type = &hashlib_hash_type; + hashlib_hash_obj_t *self = mp_obj_malloc(hashlib_hash_obj_t, &hashlib_hash_type); if (!common_hal_hashlib_new(self, algorithm)) { mp_raise_ValueError(translate("Unsupported hash algorithm")); @@ -87,4 +86,4 @@ const mp_obj_module_t hashlib_module = { .globals = (mp_obj_dict_t *)&hashlib_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_hashlib, hashlib_module, CIRCUITPY_HASHLIB); +MP_REGISTER_MODULE(MP_QSTR_hashlib, hashlib_module); diff --git a/shared-bindings/i2ctarget/I2CTarget.c b/shared-bindings/i2ctarget/I2CTarget.c index a07d038c6f269..1bc672032dad2 100644 --- a/shared-bindings/i2ctarget/I2CTarget.c +++ b/shared-bindings/i2ctarget/I2CTarget.c @@ -40,8 +40,8 @@ #include "py/runtime.h" STATIC mp_obj_t mp_obj_new_i2ctarget_i2c_target_request(i2ctarget_i2c_target_obj_t *target, uint8_t address, bool is_read, bool is_restart) { - i2ctarget_i2c_target_request_obj_t *self = m_new_obj(i2ctarget_i2c_target_request_obj_t); - self->base.type = &i2ctarget_i2c_target_request_type; + i2ctarget_i2c_target_request_obj_t *self = + mp_obj_malloc(i2ctarget_i2c_target_request_obj_t, &i2ctarget_i2c_target_request_type); self->target = target; self->address = address; self->is_read = is_read; @@ -69,8 +69,7 @@ STATIC mp_obj_t mp_obj_new_i2ctarget_i2c_target_request(i2ctarget_i2c_target_obj //| :param bool smbus: Use SMBUS timings if the hardware supports it""" //| ... STATIC mp_obj_t i2ctarget_i2c_target_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - i2ctarget_i2c_target_obj_t *self = m_new_obj(i2ctarget_i2c_target_obj_t); - self->base.type = &i2ctarget_i2c_target_type; + i2ctarget_i2c_target_obj_t *self = mp_obj_malloc(i2ctarget_i2c_target_obj_t, &i2ctarget_i2c_target_type); enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/i2ctarget/__init__.c b/shared-bindings/i2ctarget/__init__.c index 0fa7e50dd66d8..f9a358eef4eb5 100644 --- a/shared-bindings/i2ctarget/__init__.c +++ b/shared-bindings/i2ctarget/__init__.c @@ -106,7 +106,4 @@ const mp_obj_module_t i2ctarget_module = { .globals = (mp_obj_dict_t *)&i2ctarget_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_i2ctarget, i2ctarget_module, CIRCUITPY_I2CTARGET); - -// TODO: Remove for CircuitPython 9.0.0 -MP_REGISTER_MODULE(MP_QSTR_i2cperipheral, i2ctarget_module, CIRCUITPY_I2CTARGET); +MP_REGISTER_MODULE(MP_QSTR_i2ctarget, i2ctarget_module); diff --git a/shared-bindings/imagecapture/ParallelImageCapture.c b/shared-bindings/imagecapture/ParallelImageCapture.c index d568da158f3e1..56d7bfbc48b49 100644 --- a/shared-bindings/imagecapture/ParallelImageCapture.c +++ b/shared-bindings/imagecapture/ParallelImageCapture.c @@ -76,8 +76,8 @@ STATIC mp_obj_t imagecapture_parallelimagecapture_make_new(const mp_obj_type_t * const mcu_pin_obj_t *vsync = validate_obj_is_free_pin_or_none(args[ARG_vsync].u_obj, MP_QSTR_vsync); const mcu_pin_obj_t *href = validate_obj_is_free_pin_or_none(args[ARG_href].u_obj, MP_QSTR_href); - imagecapture_parallelimagecapture_obj_t *self = m_new_obj(imagecapture_parallelimagecapture_obj_t); - self->base.type = &imagecapture_parallelimagecapture_type; + imagecapture_parallelimagecapture_obj_t *self = + mp_obj_malloc(imagecapture_parallelimagecapture_obj_t, &imagecapture_parallelimagecapture_type); common_hal_imagecapture_parallelimagecapture_construct(self, pins, pin_count, clock, vsync, href); diff --git a/shared-bindings/imagecapture/__init__.c b/shared-bindings/imagecapture/__init__.c index 71d0b9125be5d..de30ec24baee0 100644 --- a/shared-bindings/imagecapture/__init__.c +++ b/shared-bindings/imagecapture/__init__.c @@ -50,4 +50,4 @@ const mp_obj_module_t imagecapture_module = { .globals = (mp_obj_dict_t *)&imagecapture_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_imagecapture, imagecapture_module, CIRCUITPY_IMAGECAPTURE); +MP_REGISTER_MODULE(MP_QSTR_imagecapture, imagecapture_module); diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c index b9a2363e09359..4f7cfc385346f 100644 --- a/shared-bindings/ipaddress/IPv4Address.c +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -77,8 +77,7 @@ STATIC mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t } - ipaddress_ipv4address_obj_t *self = m_new_obj(ipaddress_ipv4address_obj_t); - self->base.type = &ipaddress_ipv4address_type; + ipaddress_ipv4address_obj_t *self = mp_obj_malloc(ipaddress_ipv4address_obj_t, &ipaddress_ipv4address_type); common_hal_ipaddress_ipv4address_construct(self, buf, 4); diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index 6da5a5229977c..eb2b8f8ff6f6a 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -112,4 +112,4 @@ const mp_obj_module_t ipaddress_module = { .globals = (mp_obj_dict_t *)&ipaddress_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_ipaddress, ipaddress_module, CIRCUITPY_IPADDRESS); +MP_REGISTER_MODULE(MP_QSTR_ipaddress, ipaddress_module); diff --git a/shared-bindings/is31fl3741/IS31FL3741.c b/shared-bindings/is31fl3741/IS31FL3741.c index 17b12da67abde..79982b4c90e49 100644 --- a/shared-bindings/is31fl3741/IS31FL3741.c +++ b/shared-bindings/is31fl3741/IS31FL3741.c @@ -57,8 +57,7 @@ STATIC mp_obj_t is31fl3741_IS31FL3741_make_new(const mp_obj_type_t *type, size_t mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c_bus); - is31fl3741_IS31FL3741_obj_t *self = m_new_obj(is31fl3741_IS31FL3741_obj_t); - self->base.type = &is31fl3741_IS31FL3741_type; + is31fl3741_IS31FL3741_obj_t *self = mp_obj_malloc(is31fl3741_IS31FL3741_obj_t, &is31fl3741_IS31FL3741_type); common_hal_is31fl3741_IS31FL3741_construct(self, MP_OBJ_TO_PTR(i2c), diff --git a/shared-bindings/is31fl3741/__init__.c b/shared-bindings/is31fl3741/__init__.c index 605889700caf1..d7fbc5f6e6c05 100644 --- a/shared-bindings/is31fl3741/__init__.c +++ b/shared-bindings/is31fl3741/__init__.c @@ -47,4 +47,4 @@ const mp_obj_module_t is31fl3741_module = { .globals = (mp_obj_dict_t *)&is31fl3741_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_is31fl3741, is31fl3741_module, CIRCUITPY_IS31FL3741); +MP_REGISTER_MODULE(MP_QSTR_is31fl3741, is31fl3741_module); diff --git a/shared-bindings/keypad/Event.c b/shared-bindings/keypad/Event.c index 52c574e692ce8..1a3db1c61f563 100644 --- a/shared-bindings/keypad/Event.c +++ b/shared-bindings/keypad/Event.c @@ -45,8 +45,7 @@ //| """ //| ... STATIC mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - keypad_event_obj_t *self = m_new_obj(keypad_event_obj_t); - self->base.type = &keypad_event_type; + keypad_event_obj_t *self = mp_obj_malloc(keypad_event_obj_t, &keypad_event_type); enum { ARG_key_number, ARG_pressed, ARG_timestamp }; static const mp_arg_t allowed_args[] = { { MP_QSTR_key_number, MP_ARG_INT, {.u_int = 0} }, diff --git a/shared-bindings/keypad/KeyMatrix.c b/shared-bindings/keypad/KeyMatrix.c index 2209f3f68fd7a..32787f8e9d888 100644 --- a/shared-bindings/keypad/KeyMatrix.c +++ b/shared-bindings/keypad/KeyMatrix.c @@ -72,8 +72,7 @@ STATIC mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_KEYPAD_KEYMATRIX - keypad_keymatrix_obj_t *self = m_new_obj(keypad_keymatrix_obj_t); - self->base.type = &keypad_keymatrix_type; + keypad_keymatrix_obj_t *self = mp_obj_malloc(keypad_keymatrix_obj_t, &keypad_keymatrix_type); enum { ARG_row_pins, ARG_column_pins, ARG_columns_to_anodes, ARG_interval, ARG_max_events }; static const mp_arg_t allowed_args[] = { { MP_QSTR_row_pins, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/keypad/Keys.c b/shared-bindings/keypad/Keys.c index 2481fedc6b550..63a27425f5734 100644 --- a/shared-bindings/keypad/Keys.c +++ b/shared-bindings/keypad/Keys.c @@ -74,8 +74,7 @@ STATIC mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_KEYPAD_KEYS - keypad_keys_obj_t *self = m_new_obj(keypad_keys_obj_t); - self->base.type = &keypad_keys_type; + keypad_keys_obj_t *self = mp_obj_malloc(keypad_keys_obj_t, &keypad_keys_type); enum { ARG_pins, ARG_value_when_pressed, ARG_pull, ARG_interval, ARG_max_events }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pins, MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/keypad/ShiftRegisterKeys.c b/shared-bindings/keypad/ShiftRegisterKeys.c index e85e9af837d0f..83c610236f72e 100644 --- a/shared-bindings/keypad/ShiftRegisterKeys.c +++ b/shared-bindings/keypad/ShiftRegisterKeys.c @@ -85,8 +85,8 @@ STATIC mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS - keypad_shiftregisterkeys_obj_t *self = m_new_obj(keypad_shiftregisterkeys_obj_t); - self->base.type = &keypad_shiftregisterkeys_type; + keypad_shiftregisterkeys_obj_t *self = + mp_obj_malloc(keypad_shiftregisterkeys_obj_t, &keypad_shiftregisterkeys_type); enum { ARG_clock, ARG_data, ARG_latch, ARG_value_to_latch, ARG_key_count, ARG_value_when_pressed, ARG_interval, ARG_max_events }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/keypad/__init__.c b/shared-bindings/keypad/__init__.c index 7dd76c1947120..263e324b9bc5d 100644 --- a/shared-bindings/keypad/__init__.c +++ b/shared-bindings/keypad/__init__.c @@ -107,4 +107,4 @@ const mp_obj_module_t keypad_module = { .globals = (mp_obj_dict_t *)&keypad_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_keypad, keypad_module, CIRCUITPY_KEYPAD); +MP_REGISTER_MODULE(MP_QSTR_keypad, keypad_module); diff --git a/shared-bindings/math/__init__.c b/shared-bindings/math/__init__.c index 8aee44ffb8611..2c175321972ab 100644 --- a/shared-bindings/math/__init__.c +++ b/shared-bindings/math/__init__.c @@ -473,6 +473,6 @@ const mp_obj_module_t math_module = { .globals = (mp_obj_dict_t *)&mp_module_math_globals, }; -MP_REGISTER_MODULE(MP_QSTR_math, math_module, CIRCUITPY_MATH); +MP_REGISTER_MODULE(MP_QSTR_math, math_module); #endif // MICROPY_PY_BUILTINS_FLOAT diff --git a/shared-bindings/mdns/__init__.c b/shared-bindings/mdns/__init__.c index 73bd71c65cd2c..2a8cd85e390a1 100644 --- a/shared-bindings/mdns/__init__.c +++ b/shared-bindings/mdns/__init__.c @@ -52,4 +52,4 @@ const mp_obj_module_t mdns_module = { .globals = (mp_obj_dict_t *)&mdns_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_mdns, mdns_module, CIRCUITPY_MDNS); +MP_REGISTER_MODULE(MP_QSTR_mdns, mdns_module); diff --git a/shared-bindings/memorymap/AddressRange.c b/shared-bindings/memorymap/AddressRange.c index fb55c07efebd3..7fd1062534673 100644 --- a/shared-bindings/memorymap/AddressRange.c +++ b/shared-bindings/memorymap/AddressRange.c @@ -69,8 +69,7 @@ STATIC mp_obj_t memorymap_addressrange_make_new(const mp_obj_type_t *type, size_ mp_arg_validate_int_min(args[ARG_length].u_int, 1, MP_QSTR_length); - memorymap_addressrange_obj_t *self = m_new_obj(memorymap_addressrange_obj_t); - self->base.type = &memorymap_addressrange_type; + memorymap_addressrange_obj_t *self = mp_obj_malloc(memorymap_addressrange_obj_t, &memorymap_addressrange_type); common_hal_memorymap_addressrange_construct(self, (uint8_t *)start, length); diff --git a/shared-bindings/memorymap/__init__.c b/shared-bindings/memorymap/__init__.c index 576c7f1e1d59d..a276e371ba880 100644 --- a/shared-bindings/memorymap/__init__.c +++ b/shared-bindings/memorymap/__init__.c @@ -49,4 +49,4 @@ const mp_obj_module_t memorymap_module = { .globals = (mp_obj_dict_t *)&memorymap_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_memorymap, memorymap_module, CIRCUITPY_MEMORYMAP); +MP_REGISTER_MODULE(MP_QSTR_memorymap, memorymap_module); diff --git a/shared-bindings/memorymonitor/AllocationAlarm.c b/shared-bindings/memorymonitor/AllocationAlarm.c index e279fa685481e..a21a14b2f0068 100644 --- a/shared-bindings/memorymonitor/AllocationAlarm.c +++ b/shared-bindings/memorymonitor/AllocationAlarm.c @@ -66,8 +66,8 @@ STATIC mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type mp_arg_validate_int_min(args[ARG_minimum_block_count].u_int, 1, MP_QSTR_minimum_block_count); - memorymonitor_allocationalarm_obj_t *self = m_new_obj(memorymonitor_allocationalarm_obj_t); - self->base.type = &memorymonitor_allocationalarm_type; + memorymonitor_allocationalarm_obj_t *self = + mp_obj_malloc(memorymonitor_allocationalarm_obj_t, &memorymonitor_allocationalarm_type); common_hal_memorymonitor_allocationalarm_construct(self, minimum_block_count); diff --git a/shared-bindings/memorymonitor/AllocationSize.c b/shared-bindings/memorymonitor/AllocationSize.c index dd3a1e03cf780..3340f51615386 100644 --- a/shared-bindings/memorymonitor/AllocationSize.c +++ b/shared-bindings/memorymonitor/AllocationSize.c @@ -62,8 +62,8 @@ //| """ //| ... STATIC mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { - memorymonitor_allocationsize_obj_t *self = m_new_obj(memorymonitor_allocationsize_obj_t); - self->base.type = &memorymonitor_allocationsize_type; + memorymonitor_allocationsize_obj_t *self = + m_new_obj(memorymonitor_allocationsize_obj_t, &memorymonitor_allocationsize_type); common_hal_memorymonitor_allocationsize_construct(self); diff --git a/shared-bindings/memorymonitor/__init__.c b/shared-bindings/memorymonitor/__init__.c index 7b05acd095525..b7ed7566a4d15 100644 --- a/shared-bindings/memorymonitor/__init__.c +++ b/shared-bindings/memorymonitor/__init__.c @@ -45,7 +45,7 @@ MP_DEFINE_MEMORYMONITOR_EXCEPTION(AllocationError, Exception) NORETURN void mp_raise_memorymonitor_AllocationError(const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_memorymonitor_AllocationError, fmt, argptr); va_end(argptr); nlr_raise(exception); @@ -77,4 +77,4 @@ const mp_obj_module_t memorymonitor_module = { .globals = (mp_obj_dict_t *)&memorymonitor_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_memorymonitor, memorymonitor_module, CIRCUITPY_MEMORYMONITOR); +MP_REGISTER_MODULE(MP_QSTR_memorymonitor, memorymonitor_module); diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index 2c1fdd5b58237..3858cad776a8d 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -192,4 +192,4 @@ const mp_obj_module_t microcontroller_module = { .globals = (mp_obj_dict_t *)&mcu_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_microcontroller, microcontroller_module, CIRCUITPY_MICROCONTROLLER); +MP_REGISTER_MODULE(MP_QSTR_microcontroller, microcontroller_module); diff --git a/shared-bindings/msgpack/ExtType.c b/shared-bindings/msgpack/ExtType.c index 7bfe3bd8bd865..15e30c1575a60 100644 --- a/shared-bindings/msgpack/ExtType.c +++ b/shared-bindings/msgpack/ExtType.c @@ -37,8 +37,7 @@ //| :param int code: type code in range 0~127. //| :param bytes data: representation.""" STATIC mp_obj_t mod_msgpack_exttype_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - mod_msgpack_extype_obj_t *self = m_new_obj(mod_msgpack_extype_obj_t); - self->base.type = &mod_msgpack_exttype_type; + mod_msgpack_extype_obj_t *self = mp_obj_malloc(mod_msgpack_extype_obj_t, &mod_msgpack_exttype_type); enum { ARG_code, ARG_data }; static const mp_arg_t allowed_args[] = { { MP_QSTR_code, MP_ARG_INT | MP_ARG_REQUIRED }, diff --git a/shared-bindings/msgpack/__init__.c b/shared-bindings/msgpack/__init__.c index 7773d6d190fcd..fb4fe63304edf 100644 --- a/shared-bindings/msgpack/__init__.c +++ b/shared-bindings/msgpack/__init__.c @@ -174,4 +174,4 @@ const mp_obj_module_t msgpack_module = { .globals = (mp_obj_dict_t *)&msgpack_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_msgpack, msgpack_module, CIRCUITPY_MSGPACK); +MP_REGISTER_MODULE(MP_QSTR_msgpack, msgpack_module); diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c index cc0e2a041ae59..8a471f26ffa06 100644 --- a/shared-bindings/neopixel_write/__init__.c +++ b/shared-bindings/neopixel_write/__init__.c @@ -140,4 +140,4 @@ const mp_obj_module_t neopixel_write_module = { .globals = (mp_obj_dict_t *)&neopixel_write_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_neopixel_write, neopixel_write_module, CIRCUITPY_NEOPIXEL_WRITE); +MP_REGISTER_MODULE(MP_QSTR_neopixel_write, neopixel_write_module); diff --git a/shared-bindings/nvm/__init__.c b/shared-bindings/nvm/__init__.c index 0ecadd9880730..ff553741a929b 100644 --- a/shared-bindings/nvm/__init__.c +++ b/shared-bindings/nvm/__init__.c @@ -51,4 +51,4 @@ const mp_obj_module_t nvm_module = { .globals = (mp_obj_dict_t *)&nvm_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_nvm, nvm_module, CIRCUITPY_NVM); +MP_REGISTER_MODULE(MP_QSTR_nvm, nvm_module); diff --git a/shared-bindings/onewireio/OneWire.c b/shared-bindings/onewireio/OneWire.c index 3f0dc87722714..f52ebb4c6a17d 100644 --- a/shared-bindings/onewireio/OneWire.c +++ b/shared-bindings/onewireio/OneWire.c @@ -62,8 +62,7 @@ STATIC mp_obj_t onewireio_onewire_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); - onewireio_onewire_obj_t *self = m_new_obj(onewireio_onewire_obj_t); - self->base.type = &onewireio_onewire_type; + onewireio_onewire_obj_t *self = mp_obj_malloc(onewireio_onewire_obj_t, &onewireio_onewire_type); common_hal_onewireio_onewire_construct(self, pin); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/onewireio/__init__.c b/shared-bindings/onewireio/__init__.c index 282192179b26e..869300debacf1 100644 --- a/shared-bindings/onewireio/__init__.c +++ b/shared-bindings/onewireio/__init__.c @@ -51,4 +51,4 @@ const mp_obj_module_t onewireio_module = { .globals = (mp_obj_dict_t *)&onewireio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_onewireio, onewireio_module, CIRCUITPY_ONEWIREIO); +MP_REGISTER_MODULE(MP_QSTR_onewireio, onewireio_module); diff --git a/shared-bindings/os/__init__.c b/shared-bindings/os/__init__.c index 4ff48499a5305..87b77a2d6d9d6 100644 --- a/shared-bindings/os/__init__.c +++ b/shared-bindings/os/__init__.c @@ -300,4 +300,4 @@ const mp_obj_module_t os_module = { .globals = (mp_obj_dict_t *)&os_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_os, os_module, CIRCUITPY_OS); +MP_REGISTER_MODULE(MP_QSTR_os, os_module); diff --git a/shared-bindings/paralleldisplay/__init__.c b/shared-bindings/paralleldisplay/__init__.c index e87479a9f95ef..de4492f550249 100644 --- a/shared-bindings/paralleldisplay/__init__.c +++ b/shared-bindings/paralleldisplay/__init__.c @@ -48,4 +48,4 @@ const mp_obj_module_t paralleldisplay_module = { .globals = (mp_obj_dict_t *)¶lleldisplay_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_paralleldisplay, paralleldisplay_module, CIRCUITPY_PARALLELDISPLAY); +MP_REGISTER_MODULE(MP_QSTR_paralleldisplay, paralleldisplay_module); diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c index 67cffc9f7b6b1..789e1173c8dd3 100644 --- a/shared-bindings/ps2io/Ps2.c +++ b/shared-bindings/ps2io/Ps2.c @@ -78,8 +78,7 @@ STATIC mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, siz const mcu_pin_obj_t *clock_pin = validate_obj_is_free_pin(args[ARG_clock_pin].u_obj, MP_QSTR_clock_pin); const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj, MP_QSTR_data_pin); - ps2io_ps2_obj_t *self = m_new_obj(ps2io_ps2_obj_t); - self->base.type = &ps2io_ps2_type; + ps2io_ps2_obj_t *self = mp_obj_malloc(ps2io_ps2_obj_t, &ps2io_ps2_type); common_hal_ps2io_ps2_construct(self, data_pin, clock_pin); diff --git a/shared-bindings/ps2io/__init__.c b/shared-bindings/ps2io/__init__.c index 68577440368bf..e6aed10955412 100644 --- a/shared-bindings/ps2io/__init__.c +++ b/shared-bindings/ps2io/__init__.c @@ -57,4 +57,4 @@ const mp_obj_module_t ps2io_module = { .globals = (mp_obj_dict_t *)&ps2io_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_ps2io, ps2io_module, CIRCUITPY_PS2IO); +MP_REGISTER_MODULE(MP_QSTR_ps2io, ps2io_module); diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 3510f112899b1..d738726f1c3d3 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -88,8 +88,7 @@ STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); - // Make object long-lived to avoid moving between imports - pulseio_pulsein_obj_t *self = m_new_ll_obj_with_finaliser(pulseio_pulsein_obj_t); + pulseio_pulsein_obj_t *self = m_new_obj_with_finaliser(pulseio_pulsein_obj_t); self->base.type = &pulseio_pulsein_type; common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 2af07a46d8316..16777d9843610 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -81,8 +81,7 @@ STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar mp_int_t frequency = args[ARG_frequency].u_int; mp_int_t duty_cycle = args[ARG_duty_cycle].u_int; - pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t); - self->base.type = &pulseio_pulseout_type; + pulseio_pulseout_obj_t *self = mp_obj_malloc(pulseio_pulseout_obj_t, &pulseio_pulseout_type); common_hal_pulseio_pulseout_construct(self, pin, frequency, duty_cycle); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-bindings/pulseio/__init__.c b/shared-bindings/pulseio/__init__.c index c062cedd115cb..b8a190ef5d3aa 100644 --- a/shared-bindings/pulseio/__init__.c +++ b/shared-bindings/pulseio/__init__.c @@ -58,4 +58,4 @@ const mp_obj_module_t pulseio_module = { .globals = (mp_obj_dict_t *)&pulseio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_pulseio, pulseio_module, CIRCUITPY_PULSEIO); +MP_REGISTER_MODULE(MP_QSTR_pulseio, pulseio_module); diff --git a/shared-bindings/pwmio/PWMOut.c b/shared-bindings/pwmio/PWMOut.c index 784f87a025971..0c99e26a7dd81 100644 --- a/shared-bindings/pwmio/PWMOut.c +++ b/shared-bindings/pwmio/PWMOut.c @@ -176,8 +176,7 @@ STATIC mp_obj_t pwmio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, bool variable_frequency = parsed_args[ARG_variable_frequency].u_bool; // create PWM object from the given pin - pwmio_pwmout_obj_t *self = m_new_obj(pwmio_pwmout_obj_t); - self->base.type = &pwmio_pwmout_type; + pwmio_pwmout_obj_t *self = mp_obj_malloc(pwmio_pwmout_obj_t, &pwmio_pwmout_type); pwmout_result_t result = common_hal_pwmio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); common_hal_pwmio_pwmout_raise_error(result); diff --git a/shared-bindings/pwmio/__init__.c b/shared-bindings/pwmio/__init__.c index 6aeaf9c3c8f43..38388fec84206 100644 --- a/shared-bindings/pwmio/__init__.c +++ b/shared-bindings/pwmio/__init__.c @@ -74,4 +74,4 @@ const mp_obj_module_t pwmio_module = { .globals = (mp_obj_dict_t *)&pwmio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_pwmio, pwmio_module, CIRCUITPY_PWMIO); +MP_REGISTER_MODULE(MP_QSTR_pwmio, pwmio_module); diff --git a/shared-bindings/qrio/QRDecoder.c b/shared-bindings/qrio/QRDecoder.c index b37a14fd8f3ea..e8cabade33456 100644 --- a/shared-bindings/qrio/QRDecoder.c +++ b/shared-bindings/qrio/QRDecoder.c @@ -50,8 +50,7 @@ STATIC mp_obj_t qrio_qrdecoder_make_new(const mp_obj_type_t *type, size_t n_args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, args_in, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - qrio_qrdecoder_obj_t *self = m_new_obj(qrio_qrdecoder_obj_t); - self->base.type = &qrio_qrdecoder_type_obj; + qrio_qrdecoder_obj_t *self = mp_obj_malloc(qrio_qrdecoder_obj_t, &qrio_qrdecoder_type_obj); shared_module_qrio_qrdecoder_construct(self, args[ARG_width].u_int, args[ARG_height].u_int); return self; diff --git a/shared-bindings/qrio/__init__.c b/shared-bindings/qrio/__init__.c index 18c74b9a8891d..3daee820edaf3 100644 --- a/shared-bindings/qrio/__init__.c +++ b/shared-bindings/qrio/__init__.c @@ -55,4 +55,4 @@ const mp_obj_module_t qrio_module = { .globals = (mp_obj_dict_t *)&qrio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_qrio, qrio_module, CIRCUITPY_QRIO); +MP_REGISTER_MODULE(MP_QSTR_qrio, qrio_module); diff --git a/shared-bindings/rainbowio/__init__.c b/shared-bindings/rainbowio/__init__.c index 324f43198e8b7..b4a5536588d40 100644 --- a/shared-bindings/rainbowio/__init__.c +++ b/shared-bindings/rainbowio/__init__.c @@ -55,4 +55,4 @@ const mp_obj_module_t rainbowio_module = { .globals = (mp_obj_dict_t *)&rainbowio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_rainbowio, rainbowio_module, CIRCUITPY_RAINBOWIO); +MP_REGISTER_MODULE(MP_QSTR_rainbowio, rainbowio_module); diff --git a/shared-bindings/random/__init__.c b/shared-bindings/random/__init__.c index 33cd9e90d04f2..6fa9629f8c698 100644 --- a/shared-bindings/random/__init__.c +++ b/shared-bindings/random/__init__.c @@ -189,4 +189,4 @@ const mp_obj_module_t random_module = { .globals = (mp_obj_dict_t *)&mp_module_random_globals, }; -MP_REGISTER_MODULE(MP_QSTR_random, random_module, CIRCUITPY_RANDOM); +MP_REGISTER_MODULE(MP_QSTR_random, random_module); diff --git a/shared-bindings/rgbmatrix/__init__.c b/shared-bindings/rgbmatrix/__init__.c index 1e9099adb66a5..d89abf17e30cd 100644 --- a/shared-bindings/rgbmatrix/__init__.c +++ b/shared-bindings/rgbmatrix/__init__.c @@ -45,4 +45,4 @@ const mp_obj_module_t rgbmatrix_module = { .globals = (mp_obj_dict_t *)&rgbmatrix_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_rgbmatrix, rgbmatrix_module, CIRCUITPY_RGBMATRIX); +MP_REGISTER_MODULE(MP_QSTR_rgbmatrix, rgbmatrix_module); diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index 6b671194f6306..24df2b2d15c93 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -75,8 +75,7 @@ STATIC mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, const mcu_pin_obj_t *pin_a = validate_obj_is_free_pin(args[ARG_pin_a].u_obj, MP_QSTR_pin_a); const mcu_pin_obj_t *pin_b = validate_obj_is_free_pin(args[ARG_pin_b].u_obj, MP_QSTR_pin_b); - // Make long-lived because some implementations use a pointer to the object as interrupt-handler data. - rotaryio_incrementalencoder_obj_t *self = m_new_ll_obj_with_finaliser(rotaryio_incrementalencoder_obj_t); + rotaryio_incrementalencoder_obj_t *self = m_new_obj_with_finaliser(rotaryio_incrementalencoder_obj_t); self->base.type = &rotaryio_incrementalencoder_type; common_hal_rotaryio_incrementalencoder_construct(self, pin_a, pin_b); diff --git a/shared-bindings/rotaryio/__init__.c b/shared-bindings/rotaryio/__init__.c index e549ecc75e13d..d8348eb9586f8 100644 --- a/shared-bindings/rotaryio/__init__.c +++ b/shared-bindings/rotaryio/__init__.c @@ -59,4 +59,4 @@ const mp_obj_module_t rotaryio_module = { .globals = (mp_obj_dict_t *)&rotaryio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_rotaryio, rotaryio_module, CIRCUITPY_ROTARYIO); +MP_REGISTER_MODULE(MP_QSTR_rotaryio, rotaryio_module); diff --git a/shared-bindings/rtc/__init__.c b/shared-bindings/rtc/__init__.c index 0220745c0f9d4..e1220841ebbb6 100644 --- a/shared-bindings/rtc/__init__.c +++ b/shared-bindings/rtc/__init__.c @@ -87,4 +87,4 @@ const mp_obj_module_t rtc_module = { .globals = (mp_obj_dict_t *)&rtc_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_rtc, rtc_module, CIRCUITPY_RTC); +MP_REGISTER_MODULE(MP_QSTR_rtc, rtc_module); diff --git a/shared-bindings/sdcardio/SDCard.c b/shared-bindings/sdcardio/SDCard.c index ce6783477401a..4bceefba455ba 100644 --- a/shared-bindings/sdcardio/SDCard.c +++ b/shared-bindings/sdcardio/SDCard.c @@ -92,8 +92,7 @@ STATIC mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_arg busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi].u_obj, MP_QSTR_spi); const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj, MP_QSTR_cs); - sdcardio_sdcard_obj_t *self = m_new_obj(sdcardio_sdcard_obj_t); - self->base.type = &sdcardio_SDCard_type; + sdcardio_sdcard_obj_t *self = mp_obj_malloc(sdcardio_sdcard_obj_t, &sdcardio_SDCard_type); common_hal_sdcardio_sdcard_construct(self, spi, cs, args[ARG_baudrate].u_int); diff --git a/shared-bindings/sdcardio/__init__.c b/shared-bindings/sdcardio/__init__.c index c64a8a38e43b4..da97af685cbdc 100644 --- a/shared-bindings/sdcardio/__init__.c +++ b/shared-bindings/sdcardio/__init__.c @@ -46,4 +46,4 @@ const mp_obj_module_t sdcardio_module = { .globals = (mp_obj_dict_t *)&sdcardio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_sdcardio, sdcardio_module, CIRCUITPY_SDCARDIO); +MP_REGISTER_MODULE(MP_QSTR_sdcardio, sdcardio_module); diff --git a/shared-bindings/sdioio/SDCard.c b/shared-bindings/sdioio/SDCard.c index 776b20fafeb04..7ff4fb750a7df 100644 --- a/shared-bindings/sdioio/SDCard.c +++ b/shared-bindings/sdioio/SDCard.c @@ -84,8 +84,7 @@ //| ... STATIC mp_obj_t sdioio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - sdioio_sdcard_obj_t *self = m_new_obj(sdioio_sdcard_obj_t); - self->base.type = &sdioio_SDCard_type; + sdioio_sdcard_obj_t *self = mp_obj_malloc(sdioio_sdcard_obj_t, &sdioio_SDCard_type); enum { ARG_clock, ARG_command, ARG_data, ARG_frequency, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, diff --git a/shared-bindings/sdioio/__init__.c b/shared-bindings/sdioio/__init__.c index 5204da22a473a..0d15a3e5d36cd 100644 --- a/shared-bindings/sdioio/__init__.c +++ b/shared-bindings/sdioio/__init__.c @@ -46,4 +46,4 @@ const mp_obj_module_t sdioio_module = { .globals = (mp_obj_dict_t *)&sdioio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_sdioio, sdioio_module, CIRCUITPY_SDIOIO); +MP_REGISTER_MODULE(MP_QSTR_sdioio, sdioio_module); diff --git a/shared-bindings/sharpdisplay/__init__.c b/shared-bindings/sharpdisplay/__init__.c index 4726e6ea1c9dc..90e99eea1d122 100644 --- a/shared-bindings/sharpdisplay/__init__.c +++ b/shared-bindings/sharpdisplay/__init__.c @@ -48,4 +48,4 @@ const mp_obj_module_t sharpdisplay_module = { .globals = (mp_obj_dict_t *)&sharpdisplay_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_sharpdisplay, sharpdisplay_module, CIRCUITPY_SHARPDISPLAY); +MP_REGISTER_MODULE(MP_QSTR_sharpdisplay, sharpdisplay_module); diff --git a/shared-bindings/socketpool/__init__.c b/shared-bindings/socketpool/__init__.c index 48cc00245ff8f..53993a978c037 100644 --- a/shared-bindings/socketpool/__init__.c +++ b/shared-bindings/socketpool/__init__.c @@ -54,4 +54,4 @@ const mp_obj_module_t socketpool_module = { .globals = (mp_obj_dict_t *)&socketpool_globals, }; -MP_REGISTER_MODULE(MP_QSTR_socketpool, socketpool_module, CIRCUITPY_SOCKETPOOL); +MP_REGISTER_MODULE(MP_QSTR_socketpool, socketpool_module); diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c index ef227542fe073..5fc4238f751e8 100644 --- a/shared-bindings/ssl/SSLContext.c +++ b/shared-bindings/ssl/SSLContext.c @@ -45,8 +45,7 @@ STATIC mp_obj_t ssl_sslcontext_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); - ssl_sslcontext_obj_t *s = m_new_obj(ssl_sslcontext_obj_t); - s->base.type = &ssl_sslcontext_type; + ssl_sslcontext_obj_t *s = mp_obj_malloc(ssl_sslcontext_obj_t, &ssl_sslcontext_type); common_hal_ssl_sslcontext_construct(s); diff --git a/shared-bindings/ssl/__init__.c b/shared-bindings/ssl/__init__.c index 696786005410d..2e298163be440 100644 --- a/shared-bindings/ssl/__init__.c +++ b/shared-bindings/ssl/__init__.c @@ -44,8 +44,7 @@ //| STATIC mp_obj_t ssl_create_default_context(void) { - ssl_sslcontext_obj_t *s = m_new_obj(ssl_sslcontext_obj_t); - s->base.type = &ssl_sslcontext_type; + ssl_sslcontext_obj_t *s = mp_obj_malloc(ssl_sslcontext_obj_t, &ssl_sslcontext_type); common_hal_ssl_create_default_context(s); return s; @@ -67,4 +66,4 @@ const mp_obj_module_t ssl_module = { .globals = (mp_obj_dict_t *)&ssl_globals, }; -MP_REGISTER_MODULE(MP_QSTR_ssl, ssl_module, CIRCUITPY_SSL); +MP_REGISTER_MODULE(MP_QSTR_ssl, ssl_module); diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index c4bd728f67d85..b774c5550ee74 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -314,4 +314,4 @@ const mp_obj_module_t storage_module = { .globals = (mp_obj_dict_t *)&storage_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_storage, storage_module, CIRCUITPY_STORAGE); +MP_REGISTER_MODULE(MP_QSTR_storage, storage_module); diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c index 5b63a15f15991..519b1ace66c65 100644 --- a/shared-bindings/struct/__init__.c +++ b/shared-bindings/struct/__init__.c @@ -178,4 +178,4 @@ const mp_obj_module_t struct_module = { .globals = (mp_obj_dict_t *)&mp_module_struct_globals, }; -MP_REGISTER_MODULE(MP_QSTR_struct, struct_module, CIRCUITPY_STRUCT); +MP_REGISTER_MODULE(MP_QSTR_struct, struct_module); diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index 491cac2f17e21..a1820e215e01e 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -233,8 +233,7 @@ STATIC mp_obj_t supervisor_get_previous_traceback(void) { if (prev_traceback_allocation) { size_t len = strlen((const char *)prev_traceback_allocation->ptr); if (len > 0) { - mp_obj_str_t *o = m_new_obj(mp_obj_str_t); - o->base.type = &mp_type_str; + mp_obj_str_t *o = mp_obj_malloc(mp_obj_str_t, &mp_type_str); o->len = len; // callers probably aren't going to compare this string, so skip computing the hash o->hash = 0; @@ -356,4 +355,4 @@ const mp_obj_module_t supervisor_module = { .globals = (mp_obj_dict_t *)&supervisor_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_supervisor, supervisor_module, CIRCUITPY_SUPERVISOR); +MP_REGISTER_MODULE(MP_QSTR_supervisor, supervisor_module); diff --git a/shared-bindings/synthio/LFO.c b/shared-bindings/synthio/LFO.c index 00be16a15c50a..86e32999cf5ee 100644 --- a/shared-bindings/synthio/LFO.c +++ b/shared-bindings/synthio/LFO.c @@ -88,8 +88,7 @@ STATIC mp_obj_t synthio_lfo_make_new(const mp_obj_type_t *type_in, size_t n_args mp_arg_val_t args[MP_ARRAY_SIZE(lfo_properties)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(lfo_properties), lfo_properties, args); - synthio_lfo_obj_t *self = m_new_obj(synthio_lfo_obj_t); - self->base.base.type = &synthio_lfo_type; + synthio_lfo_obj_t *self = mp_obj_malloc(synthio_lfo_obj_t, &synthio_lfo_type); self->waveform_bufinfo = ((mp_buffer_info_t) {.buf = (void *)triangle, .len = MP_ARRAY_SIZE(triangle)}); if (args[ARG_waveform].u_obj != mp_const_none) { diff --git a/shared-bindings/synthio/Math.c b/shared-bindings/synthio/Math.c index 57902b0dd0542..ea75b7c4bfcbc 100644 --- a/shared-bindings/synthio/Math.c +++ b/shared-bindings/synthio/Math.c @@ -172,8 +172,7 @@ STATIC mp_obj_t synthio_math_make_new(const mp_obj_type_t *type_in, size_t n_arg } STATIC mp_obj_t synthio_math_make_new_common(mp_arg_val_t args[MP_ARRAY_SIZE(math_properties)]) { - synthio_math_obj_t *self = m_new_obj(synthio_math_obj_t); - self->base.base.type = &synthio_math_type; + synthio_math_obj_t *self = mp_obj_malloc(synthio_math_obj_t, &synthio_math_type); self->base.last_tick = synthio_global_tick; diff --git a/shared-bindings/synthio/MidiTrack.c b/shared-bindings/synthio/MidiTrack.c index 2d0d2ab69f8c8..79af9e9744fd0 100644 --- a/shared-bindings/synthio/MidiTrack.c +++ b/shared-bindings/synthio/MidiTrack.c @@ -88,8 +88,7 @@ STATIC mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); - synthio_miditrack_obj_t *self = m_new_obj(synthio_miditrack_obj_t); - self->base.type = &synthio_miditrack_type; + synthio_miditrack_obj_t *self = mp_obj_malloc(synthio_miditrack_obj_t, &synthio_miditrack_type); common_hal_synthio_miditrack_construct(self, (uint8_t *)bufinfo.buf, bufinfo.len, diff --git a/shared-bindings/synthio/Note.c b/shared-bindings/synthio/Note.c index 4dcc66666c980..a1d0effbed35c 100644 --- a/shared-bindings/synthio/Note.c +++ b/shared-bindings/synthio/Note.c @@ -71,8 +71,7 @@ STATIC mp_obj_t synthio_note_make_new(const mp_obj_type_t *type_in, size_t n_arg mp_arg_val_t args[MP_ARRAY_SIZE(note_properties)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(note_properties), note_properties, args); - synthio_note_obj_t *self = m_new_obj(synthio_note_obj_t); - self->base.type = &synthio_note_type; + synthio_note_obj_t *self = mp_obj_malloc(synthio_note_obj_t, &synthio_note_type); mp_obj_t result = MP_OBJ_FROM_PTR(self); properties_construct_helper(result, note_properties, args, MP_ARRAY_SIZE(note_properties)); diff --git a/shared-bindings/synthio/Synthesizer.c b/shared-bindings/synthio/Synthesizer.c index 25d26fc66162c..aa3d74e0155a4 100644 --- a/shared-bindings/synthio/Synthesizer.c +++ b/shared-bindings/synthio/Synthesizer.c @@ -79,8 +79,7 @@ STATIC mp_obj_t synthio_synthesizer_make_new(const mp_obj_type_t *type, size_t n mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - synthio_synthesizer_obj_t *self = m_new_obj(synthio_synthesizer_obj_t); - self->base.type = &synthio_synthesizer_type; + synthio_synthesizer_obj_t *self = mp_obj_malloc(synthio_synthesizer_obj_t, &synthio_synthesizer_type); common_hal_synthio_synthesizer_construct(self, args[ARG_sample_rate].u_int, diff --git a/shared-bindings/synthio/__init__.c b/shared-bindings/synthio/__init__.c index 48a4d407c7bdd..6f0fbd278298a 100644 --- a/shared-bindings/synthio/__init__.c +++ b/shared-bindings/synthio/__init__.c @@ -272,7 +272,7 @@ STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma } uint32_t track_size = (chunk_header[4] << 24) | (chunk_header[5] << 16) | (chunk_header[6] << 8) | chunk_header[7]; - uint8_t *buffer = m_malloc(track_size, false); + uint8_t *buffer = m_malloc(track_size); if (f_read(&file->fp, buffer, track_size, &bytes_read) != FR_OK) { mp_raise_OSError(MP_EIO); } @@ -280,8 +280,7 @@ STATIC mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma mp_arg_error_invalid(MP_QSTR_file); } - synthio_miditrack_obj_t *result = m_new_obj(synthio_miditrack_obj_t); - result->base.type = &synthio_miditrack_type; + synthio_miditrack_obj_t *result = mp_obj_malloc(synthio_miditrack_obj_t, &synthio_miditrack_type); common_hal_synthio_miditrack_construct(result, buffer, track_size, tempo, args[ARG_sample_rate].u_int, args[ARG_waveform].u_obj, @@ -362,4 +361,4 @@ const mp_obj_module_t synthio_module = { .globals = (mp_obj_dict_t *)&synthio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_synthio, synthio_module, CIRCUITPY_SYNTHIO); +MP_REGISTER_MODULE(MP_QSTR_synthio, synthio_module); diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c index 164999093ade6..05c10f2887d86 100644 --- a/shared-bindings/terminalio/Terminal.c +++ b/shared-bindings/terminalio/Terminal.c @@ -88,8 +88,7 @@ STATIC mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n mp_arg_validate_int_min(scroll_area->width_in_tiles, 2, MP_QSTR_scroll_area_width); mp_arg_validate_int_min(scroll_area->height_in_tiles, 2, MP_QSTR_scroll_area_height); - terminalio_terminal_obj_t *self = m_new_obj(terminalio_terminal_obj_t); - self->base.type = &terminalio_terminal_type; + terminalio_terminal_obj_t *self = mp_obj_malloc(terminalio_terminal_obj_t, &terminalio_terminal_type); common_hal_terminalio_terminal_construct(self, scroll_area, font, status_bar); return MP_OBJ_FROM_PTR(self); diff --git a/shared-bindings/terminalio/__init__.c b/shared-bindings/terminalio/__init__.c index a5980a8b9b067..3492390e5a767 100644 --- a/shared-bindings/terminalio/__init__.c +++ b/shared-bindings/terminalio/__init__.c @@ -61,4 +61,4 @@ const mp_obj_module_t terminalio_module = { .globals = (mp_obj_dict_t *)&terminalio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_terminalio, terminalio_module, CIRCUITPY_DISPLAYIO && CIRCUITPY_TERMINALIO); +MP_REGISTER_MODULE(MP_QSTR_terminalio, terminalio_module); diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index d02923f162663..a4e5033def03c 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -343,4 +343,4 @@ const mp_obj_module_t time_module = { .globals = (mp_obj_dict_t *)&time_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_time, time_module, CIRCUITPY_TIME); +MP_REGISTER_MODULE(MP_QSTR_time, time_module); diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index 7f26149b00929..64de6e18b0ed4 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -65,8 +65,7 @@ STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, // 1st argument is the pin const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0], MP_QSTR_pin); - touchio_touchin_obj_t *self = m_new_obj(touchio_touchin_obj_t); - self->base.type = &touchio_touchin_type; + touchio_touchin_obj_t *self = mp_obj_malloc(touchio_touchin_obj_t, &touchio_touchin_type); common_hal_touchio_touchin_construct(self, pin); return (mp_obj_t)self; diff --git a/shared-bindings/touchio/__init__.c b/shared-bindings/touchio/__init__.c index 8501315ca777d..502b3efa5ad5f 100644 --- a/shared-bindings/touchio/__init__.c +++ b/shared-bindings/touchio/__init__.c @@ -71,4 +71,4 @@ const mp_obj_module_t touchio_module = { .globals = (mp_obj_dict_t *)&touchio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_touchio, touchio_module, CIRCUITPY_TOUCHIO); +MP_REGISTER_MODULE(MP_QSTR_touchio, touchio_module); diff --git a/shared-bindings/traceback/__init__.c b/shared-bindings/traceback/__init__.c index 3ad601eb39452..ca341618422fd 100644 --- a/shared-bindings/traceback/__init__.c +++ b/shared-bindings/traceback/__init__.c @@ -59,7 +59,9 @@ STATIC void traceback_exception_common(bool is_print_exception, mp_print_t *prin } mp_obj_t tb_obj = args[ARG_tb].u_obj; mp_obj_t limit_obj = args[ARG_limit].u_obj; + #if MICROPY_CPYTHON_EXCEPTION_CHAIN bool chain = args[ARG_chain].u_bool; + #endif if (args[ARG_file].u_obj != mp_const_none) { if (!is_print_exception) { @@ -216,4 +218,4 @@ const mp_obj_module_t traceback_module = { .globals = (mp_obj_dict_t *)&traceback_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_traceback, traceback_module, CIRCUITPY_TRACEBACK); +MP_REGISTER_MODULE(MP_QSTR_traceback, traceback_module); diff --git a/shared-bindings/uheap/__init__.c b/shared-bindings/uheap/__init__.c index 40aa869225dba..08a8592a4d9b9 100644 --- a/shared-bindings/uheap/__init__.c +++ b/shared-bindings/uheap/__init__.c @@ -58,4 +58,4 @@ const mp_obj_module_t uheap_module = { .globals = (mp_obj_dict_t *)&uheap_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_uheap, uheap_module, CIRCUITPY_UHEAP); +MP_REGISTER_MODULE(MP_QSTR_uheap, uheap_module); diff --git a/shared-bindings/usb/__init__.c b/shared-bindings/usb/__init__.c index 1227db01e195d..60297dcab0687 100644 --- a/shared-bindings/usb/__init__.c +++ b/shared-bindings/usb/__init__.c @@ -50,4 +50,4 @@ const mp_obj_module_t usb_module = { .globals = (mp_obj_dict_t *)&usb_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_usb, usb_module, CIRCUITPY_USB_HOST); +MP_REGISTER_MODULE(MP_QSTR_usb, usb_module); diff --git a/shared-bindings/usb/core/Device.c b/shared-bindings/usb/core/Device.c index 7af131cde7cf9..d700ccef8663d 100644 --- a/shared-bindings/usb/core/Device.c +++ b/shared-bindings/usb/core/Device.c @@ -319,7 +319,7 @@ STATIC const mp_rom_map_elem_t usb_core_device_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_product), MP_ROM_PTR(&usb_core_device_product_obj) }, { MP_ROM_QSTR(MP_QSTR_manufacturer), MP_ROM_PTR(&usb_core_device_manufacturer_obj) }, - { MP_ROM_QSTR(MP_QSTR_set_configuration),MP_ROM_PTR(&usb_core_device_set_configuration_obj) }, + { MP_ROM_QSTR(MP_QSTR_set_configuration), MP_ROM_PTR(&usb_core_device_set_configuration_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&usb_core_device_write_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&usb_core_device_read_obj) }, { MP_ROM_QSTR(MP_QSTR_ctrl_transfer), MP_ROM_PTR(&usb_core_device_ctrl_transfer_obj) }, diff --git a/shared-bindings/usb/core/__init__.c b/shared-bindings/usb/core/__init__.c index 7c171e85d669f..ab7e0a2020166 100644 --- a/shared-bindings/usb/core/__init__.c +++ b/shared-bindings/usb/core/__init__.c @@ -54,7 +54,7 @@ NORETURN void mp_raise_usb_core_USBError(const compressed_string_t *fmt, ...) { exception = mp_obj_new_exception(&mp_type_usb_core_USBError); } else { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); exception = mp_obj_new_exception_msg_vlist(&mp_type_usb_core_USBError, fmt, argptr); va_end(argptr); } @@ -105,8 +105,7 @@ STATIC mp_obj_t _next_device(usb_core_devices_obj_t *iter) { // We passed the filters. Now make a properly allocated object to // return to the user. - usb_core_device_obj_t *self = m_new_obj(usb_core_device_obj_t); - self->base.type = &usb_core_device_type; + usb_core_device_obj_t *self = mp_obj_malloc(usb_core_device_obj_t, &usb_core_device_type); common_hal_usb_core_device_construct(self, i); iter->next_index = i + 1; @@ -200,4 +199,4 @@ const mp_obj_module_t usb_core_module = { .globals = (mp_obj_dict_t *)&usb_core_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_usb_dot_core, usb_core_module, CIRCUITPY_USB_HOST); +MP_REGISTER_MODULE(MP_QSTR_usb_dot_core, usb_core_module); diff --git a/shared-bindings/usb_cdc/__init__.c b/shared-bindings/usb_cdc/__init__.c index b4e712e854ca9..e7a13a768af6d 100644 --- a/shared-bindings/usb_cdc/__init__.c +++ b/shared-bindings/usb_cdc/__init__.c @@ -142,4 +142,4 @@ void usb_cdc_set_data(mp_obj_t serial_obj) { set_module_dict_entry(MP_ROM_QSTR(MP_QSTR_data), serial_obj); } -MP_REGISTER_MODULE(MP_QSTR_usb_cdc, usb_cdc_module, CIRCUITPY_USB_CDC); +MP_REGISTER_MODULE(MP_QSTR_usb_cdc, usb_cdc_module); diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index cb88766b3e033..34b496a90e57e 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -91,8 +91,7 @@ //| Uses Report ID 3 for its IN report.""" STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - usb_hid_device_obj_t *self = m_new_obj(usb_hid_device_obj_t); - self->base.type = &usb_hid_device_type; + usb_hid_device_obj_t *self = mp_obj_malloc(usb_hid_device_obj_t, &usb_hid_device_type); enum { ARG_report_descriptor, ARG_usage_page, ARG_usage, ARG_report_ids, ARG_in_report_lengths, ARG_out_report_lengths }; static const mp_arg_t allowed_args[] = { { MP_QSTR_report_descriptor, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h index dde66e2700d2a..b0df43858f1d6 100644 --- a/shared-bindings/usb_hid/Device.h +++ b/shared-bindings/usb_hid/Device.h @@ -33,7 +33,7 @@ extern const mp_obj_type_t usb_hid_device_type; -void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint16_t usage_page, uint16_t usage, size_t report_ids_count,uint8_t *report_ids, uint8_t *in_report_lengths, uint8_t *out_report_lengths); +void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint16_t usage_page, uint16_t usage, size_t report_ids_count, uint8_t *report_ids, uint8_t *in_report_lengths, uint8_t *out_report_lengths); void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *report, uint8_t len, uint8_t report_id); mp_obj_t common_hal_usb_hid_device_get_last_received_report(usb_hid_device_obj_t *self, uint8_t report_id); uint16_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self); diff --git a/shared-bindings/usb_hid/__init__.c b/shared-bindings/usb_hid/__init__.c index 5c61cc52deddd..2f374084bbe95 100644 --- a/shared-bindings/usb_hid/__init__.c +++ b/shared-bindings/usb_hid/__init__.c @@ -182,4 +182,4 @@ void usb_hid_set_devices(mp_obj_t devices) { } } -MP_REGISTER_MODULE(MP_QSTR_usb_hid, usb_hid_module, CIRCUITPY_USB_HID); +MP_REGISTER_MODULE(MP_QSTR_usb_hid, usb_hid_module); diff --git a/shared-bindings/usb_host/__init__.c b/shared-bindings/usb_host/__init__.c index 74ee78b3b34a3..6a683df503c75 100644 --- a/shared-bindings/usb_host/__init__.c +++ b/shared-bindings/usb_host/__init__.c @@ -82,4 +82,4 @@ const mp_obj_module_t usb_host_module = { .globals = (mp_obj_dict_t *)&usb_host_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_usb_host, usb_host_module, CIRCUITPY_USB_HOST); +MP_REGISTER_MODULE(MP_QSTR_usb_host, usb_host_module); diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c index d3d5cf2626fa7..651f4a51d1f27 100644 --- a/shared-bindings/usb_midi/__init__.c +++ b/shared-bindings/usb_midi/__init__.c @@ -96,4 +96,4 @@ const mp_obj_module_t usb_midi_module = { .globals = (mp_obj_dict_t *)&usb_midi_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_usb_midi, usb_midi_module, CIRCUITPY_USB_MIDI); +MP_REGISTER_MODULE(MP_QSTR_usb_midi, usb_midi_module); diff --git a/shared-bindings/ustack/__init__.c b/shared-bindings/ustack/__init__.c index 17bdcbb1c0a93..b3850e42abd50 100644 --- a/shared-bindings/ustack/__init__.c +++ b/shared-bindings/ustack/__init__.c @@ -86,4 +86,4 @@ const mp_obj_module_t ustack_module = { .globals = (mp_obj_dict_t *)&ustack_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_ustack, ustack_module, CIRCUITPY_USTACK); +MP_REGISTER_MODULE(MP_QSTR_ustack, ustack_module); diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index 9896876a8a2b9..308e828a02527 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -41,8 +41,7 @@ static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_arg mp_int_t radius = args[ARG_radius].u_int; mp_arg_validate_int_min(radius, 1, MP_QSTR_radius); - vectorio_circle_t *self = m_new_obj(vectorio_circle_t); - self->base.type = &vectorio_circle_type; + vectorio_circle_t *self = mp_obj_malloc(vectorio_circle_t, &vectorio_circle_type); uint16_t color_index = args[ARG_color_index].u_int; common_hal_vectorio_circle_construct(self, radius, color_index); diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index b188fc49554a6..452631eddcb3f 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -48,8 +48,7 @@ static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_ar mp_obj_t points_list = mp_arg_validate_type(args[ARG_points_list].u_obj, &mp_type_list, MP_QSTR_points); - vectorio_polygon_t *self = m_new_obj(vectorio_polygon_t); - self->base.type = &vectorio_polygon_type; + vectorio_polygon_t *self = mp_obj_malloc(vectorio_polygon_t, &vectorio_polygon_type); uint16_t color_index = args[ARG_color_index].u_int; common_hal_vectorio_polygon_construct(self, points_list, color_index); diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index ad864f2c2d019..01453693f862c 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -45,8 +45,7 @@ static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_ mp_int_t height = args[ARG_height].u_int; mp_arg_validate_int_min(height, 1, MP_QSTR_height); - vectorio_rectangle_t *self = m_new_obj(vectorio_rectangle_t); - self->base.type = &vectorio_rectangle_type; + vectorio_rectangle_t *self = mp_obj_malloc(vectorio_rectangle_t, &vectorio_rectangle_type); uint16_t color_index = args[ARG_color_index].u_int; common_hal_vectorio_rectangle_construct(self, width, height, color_index); diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index e5c806b94376a..06a8355e2d66f 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -47,8 +47,7 @@ mp_obj_t vectorio_vector_shape_make_new(const mp_obj_t shape, const mp_obj_t pix mp_raise_TypeError_varg(translate("unsupported %q type"), MP_QSTR_shape); } - vectorio_vector_shape_t *self = m_new_obj(vectorio_vector_shape_t); - self->base.type = &vectorio_vector_shape_type; + vectorio_vector_shape_t *self = mp_obj_malloc(vectorio_vector_shape_t, &vectorio_vector_shape_type); common_hal_vectorio_vector_shape_construct(self, ishape, pixel_shader, x, y ); diff --git a/shared-bindings/vectorio/__init__.c b/shared-bindings/vectorio/__init__.c index 7ad77da681782..8e6c9766c3d52 100644 --- a/shared-bindings/vectorio/__init__.c +++ b/shared-bindings/vectorio/__init__.c @@ -45,4 +45,4 @@ const mp_obj_module_t vectorio_module = { .globals = (mp_obj_dict_t *)&vectorio_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_vectorio, vectorio_module, CIRCUITPY_VECTORIO); +MP_REGISTER_MODULE(MP_QSTR_vectorio, vectorio_module); diff --git a/shared-bindings/watchdog/__init__.c b/shared-bindings/watchdog/__init__.c index 5281f1c3fc366..70aaddc8a5208 100644 --- a/shared-bindings/watchdog/__init__.c +++ b/shared-bindings/watchdog/__init__.c @@ -106,4 +106,4 @@ const mp_obj_module_t watchdog_module = { .globals = (mp_obj_dict_t *)&watchdog_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_watchdog, watchdog_module, CIRCUITPY_WATCHDOG); +MP_REGISTER_MODULE(MP_QSTR_watchdog, watchdog_module); diff --git a/shared-bindings/wifi/Monitor.c b/shared-bindings/wifi/Monitor.c index d087ec587b9b9..acbc63ec89d19 100644 --- a/shared-bindings/wifi/Monitor.c +++ b/shared-bindings/wifi/Monitor.c @@ -59,8 +59,7 @@ STATIC mp_obj_t wifi_monitor_make_new(const mp_obj_type_t *type, size_t n_args, wifi_monitor_obj_t *self = MP_STATE_VM(wifi_monitor_singleton); if (common_hal_wifi_monitor_deinited()) { - self = m_new_obj(wifi_monitor_obj_t); - self->base.type = &wifi_monitor_type; + self = mp_obj_malloc(wifi_monitor_obj_t, &wifi_monitor_type); common_hal_wifi_monitor_construct(self, channel, queue); MP_STATE_VM(wifi_monitor_singleton) = self; } diff --git a/shared-bindings/wifi/__init__.c b/shared-bindings/wifi/__init__.c index f7b66c68ca4fc..9786c594bdae5 100644 --- a/shared-bindings/wifi/__init__.c +++ b/shared-bindings/wifi/__init__.c @@ -70,4 +70,4 @@ const mp_obj_module_t wifi_module = { .globals = (mp_obj_dict_t *)&wifi_module_globals, }; -MP_REGISTER_MODULE(MP_QSTR_wifi, wifi_module, CIRCUITPY_WIFI); +MP_REGISTER_MODULE(MP_QSTR_wifi, wifi_module); diff --git a/shared-bindings/zlib/__init__.c b/shared-bindings/zlib/__init__.c index 3b45e605e6525..d0fd803d3a20d 100644 --- a/shared-bindings/zlib/__init__.c +++ b/shared-bindings/zlib/__init__.c @@ -92,4 +92,4 @@ const mp_obj_module_t zlib_module = { .globals = (mp_obj_dict_t *)&zlib_globals, }; -MP_REGISTER_MODULE(MP_QSTR_zlib, zlib_module, CIRCUITPY_ZLIB); +MP_REGISTER_MODULE(MP_QSTR_zlib, zlib_module); diff --git a/shared-module/_bleio/ScanResults.c b/shared-module/_bleio/ScanResults.c index 1f4dbff31004a..cf4357929b3d5 100644 --- a/shared-module/_bleio/ScanResults.c +++ b/shared-module/_bleio/ScanResults.c @@ -35,9 +35,8 @@ #include "shared-bindings/_bleio/ScanResults.h" bleio_scanresults_obj_t *shared_module_bleio_new_scanresults(size_t buffer_size, uint8_t *prefixes, size_t prefixes_len, mp_int_t minimum_rssi) { - bleio_scanresults_obj_t *self = m_new_obj(bleio_scanresults_obj_t); - self->base.type = &bleio_scanresults_type; - ringbuf_alloc(&self->buf, buffer_size, false); + bleio_scanresults_obj_t *self = mp_obj_malloc(bleio_scanresults_obj_t, &bleio_scanresults_type); + ringbuf_alloc(&self->buf, buffer_size); self->prefixes = prefixes; self->prefix_length = prefixes_len; self->minimum_rssi = minimum_rssi; @@ -68,12 +67,10 @@ mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self) { mp_obj_str_t *o = MP_OBJ_TO_PTR(mp_obj_new_bytes_of_zeros(len)); ringbuf_get_n(&self->buf, (uint8_t *)o->data, len); - bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t); - entry->base.type = &bleio_scanentry_type; + bleio_scanentry_obj_t *entry = mp_obj_malloc(bleio_scanentry_obj_t, &bleio_scanentry_type); entry->rssi = rssi; - bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t); - address->base.type = &bleio_address_type; + bleio_address_obj_t *address = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); common_hal_bleio_address_construct(MP_OBJ_TO_PTR(address), peer_addr, addr_type); entry->address = address; diff --git a/shared-module/adafruit_pixelbuf/PixelBuf.c b/shared-module/adafruit_pixelbuf/PixelBuf.c index ca8f1c05b0902..9c12dd68de635 100644 --- a/shared-module/adafruit_pixelbuf/PixelBuf.c +++ b/shared-module/adafruit_pixelbuf/PixelBuf.c @@ -123,7 +123,7 @@ void common_hal_adafruit_pixelbuf_pixelbuf_set_brightness(mp_obj_t self_in, mp_f return; } else { if (self->pre_brightness_buffer == NULL) { - self->pre_brightness_buffer = m_malloc(pixel_len, false); + self->pre_brightness_buffer = m_malloc(pixel_len); memcpy(self->pre_brightness_buffer, self->post_brightness_buffer, pixel_len); } for (size_t i = 0; i < pixel_len; i++) { diff --git a/shared-module/aesio/aes.c b/shared-module/aesio/aes.c index f417e76de6466..70984a141f5fb 100644 --- a/shared-module/aesio/aes.c +++ b/shared-module/aesio/aes.c @@ -293,7 +293,7 @@ void AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t *iv) { // This function adds the round key to state. The round key is added to the // state by an XOR function. static void AddRoundKey(uint8_t round, state_t *state, const uint8_t *RoundKey) { - uint8_t i,j; + uint8_t i, j; for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) diff --git a/shared-module/atexit/__init__.c b/shared-module/atexit/__init__.c index 56271bbab884b..02749a45a1934 100644 --- a/shared-module/atexit/__init__.c +++ b/shared-module/atexit/__init__.c @@ -50,7 +50,7 @@ void shared_module_atexit_register(mp_obj_t *func, size_t n_args, const mp_obj_t .n_pos = 0, .n_kw = 0, .func = func, - .args = (n_args + n_kw_args) ? m_malloc((n_args + (n_kw_args * 2)) * sizeof(mp_obj_t), false) : NULL + .args = (n_args + n_kw_args) ? m_malloc((n_args + (n_kw_args * 2)) * sizeof(mp_obj_t)) : NULL }; for (; cb.n_pos < n_args; cb.n_pos++) { cb.args[cb.n_pos] = pos_args[cb.n_pos]; diff --git a/shared-module/audiocore/WaveFile.c b/shared-module/audiocore/WaveFile.c index 1b87532551578..590148f5c3e1e 100644 --- a/shared-module/audiocore/WaveFile.c +++ b/shared-module/audiocore/WaveFile.c @@ -118,13 +118,13 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t *self, self->second_buffer = buffer + self->len; } else { self->len = 256; - self->buffer = m_malloc(self->len, false); + self->buffer = m_malloc(self->len); if (self->buffer == NULL) { common_hal_audioio_wavefile_deinit(self); m_malloc_fail(self->len); } - self->second_buffer = m_malloc(self->len, false); + self->second_buffer = m_malloc(self->len); if (self->second_buffer == NULL) { common_hal_audioio_wavefile_deinit(self); m_malloc_fail(self->len); diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index 397a837133185..5a0338cb4a6e3 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -47,13 +47,13 @@ void common_hal_audiomixer_mixer_construct(audiomixer_mixer_obj_t *self, uint32_t sample_rate) { self->len = buffer_size / 2 / sizeof(uint32_t) * sizeof(uint32_t); - self->first_buffer = m_malloc(self->len, false); + self->first_buffer = m_malloc(self->len); if (self->first_buffer == NULL) { common_hal_audiomixer_mixer_deinit(self); m_malloc_fail(self->len); } - self->second_buffer = m_malloc(self->len, false); + self->second_buffer = m_malloc(self->len); if (self->second_buffer == NULL) { common_hal_audiomixer_mixer_deinit(self); m_malloc_fail(self->len); diff --git a/shared-module/audiomp3/MP3Decoder.c b/shared-module/audiomp3/MP3Decoder.c index 506ed5eff2505..21385670a2d3f 100644 --- a/shared-module/audiomp3/MP3Decoder.c +++ b/shared-module/audiomp3/MP3Decoder.c @@ -190,7 +190,7 @@ void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t *self, self->inbuf_length = 2048; self->inbuf_offset = self->inbuf_length; - self->inbuf = m_malloc(self->inbuf_length, false); + self->inbuf = m_malloc(self->inbuf_length); if (self->inbuf == NULL) { common_hal_audiomp3_mp3file_deinit(self); m_malloc_fail(self->inbuf_length); @@ -210,13 +210,13 @@ void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t *self, self->buffers[0] = (int16_t *)(void *)buffer; self->buffers[1] = (int16_t *)(void *)(buffer + MAX_BUFFER_LEN); } else { - self->buffers[0] = m_malloc(MAX_BUFFER_LEN, false); + self->buffers[0] = m_malloc(MAX_BUFFER_LEN); if (self->buffers[0] == NULL) { common_hal_audiomp3_mp3file_deinit(self); m_malloc_fail(MAX_BUFFER_LEN); } - self->buffers[1] = m_malloc(MAX_BUFFER_LEN, false); + self->buffers[1] = m_malloc(MAX_BUFFER_LEN); if (self->buffers[1] == NULL) { common_hal_audiomp3_mp3file_deinit(self); m_malloc_fail(MAX_BUFFER_LEN); diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 2054ff9cab633..02eaae2d46739 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -103,7 +103,7 @@ void common_hal_bitmaptools_rotozoom(displayio_bitmap_t *self, int16_t ox, int16 // # */ - int16_t x,y; + int16_t x, y; int16_t minx = dest_clip1_x; int16_t miny = dest_clip1_y; diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index 794e2dac194e2..82eca02197c3b 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -51,7 +51,7 @@ void common_hal_displayio_bitmap_construct_from_buffer(displayio_bitmap_t *self, self->stride = stride(width, bits_per_value); self->data_alloc = false; if (!data) { - data = m_malloc(self->stride * height * sizeof(uint32_t), false); + data = m_malloc(self->stride * height * sizeof(uint32_t)); self->data_alloc = true; } self->data = data; diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c index 112f7f9ad1745..9c81ec27a117d 100644 --- a/shared-module/displayio/ColorConverter.c +++ b/shared-module/displayio/ColorConverter.c @@ -263,23 +263,23 @@ uint32_t displayio_colorconverter_convert_pixel(displayio_colorspace_t colorspac void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dither, const displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color) { uint32_t pixel = input_pixel->pixel; if (dither) { - uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y)); - uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x + 33,input_pixel->tile_y)); - uint8_t randb = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x,input_pixel->tile_y + 33)); + uint8_t randr = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x, input_pixel->tile_y)); + uint8_t randg = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x + 33, input_pixel->tile_y)); + uint8_t randb = (displayio_colorconverter_dither_noise_2(input_pixel->tile_x, input_pixel->tile_y + 33)); uint32_t r8 = (pixel >> 16); uint32_t g8 = (pixel >> 8) & 0xff; uint32_t b8 = pixel & 0xff; if (colorspace->depth == 16) { - b8 = MIN(255,b8 + (randb & 0x07)); - r8 = MIN(255,r8 + (randr & 0x07)); - g8 = MIN(255,g8 + (randg & 0x03)); + b8 = MIN(255, b8 + (randb & 0x07)); + r8 = MIN(255, r8 + (randr & 0x07)); + g8 = MIN(255, g8 + (randg & 0x03)); } else { int bitmask = 0xFF >> colorspace->depth; - b8 = MIN(255,b8 + (randb & bitmask)); - r8 = MIN(255,r8 + (randr & bitmask)); - g8 = MIN(255,g8 + (randg & bitmask)); + b8 = MIN(255, b8 + (randb & bitmask)); + r8 = MIN(255, r8 + (randr & bitmask)); + g8 = MIN(255, g8 + (randg & bitmask)); } pixel = r8 << 16 | g8 << 8 | b8; } diff --git a/shared-module/displayio/OnDiskBitmap.c b/shared-module/displayio/OnDiskBitmap.c index c9a9d7d9f2e2f..789b84787a81e 100644 --- a/shared-module/displayio/OnDiskBitmap.c +++ b/shared-module/displayio/OnDiskBitmap.c @@ -67,8 +67,8 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, self->width = read_word(bmp_header, 9); self->height = read_word(bmp_header, 11); - displayio_colorconverter_t *colorconverter = m_new_obj(displayio_colorconverter_t); - colorconverter->base.type = &displayio_colorconverter_type; + displayio_colorconverter_t *colorconverter = + mp_obj_malloc(displayio_colorconverter_t, &displayio_colorconverter_type); common_hal_displayio_colorconverter_construct(colorconverter, false, DISPLAYIO_COLORSPACE_RGB888); self->colorconverter = colorconverter; @@ -88,15 +88,14 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, number_of_colors = 1 << bits_per_pixel; } - displayio_palette_t *palette = m_new_obj(displayio_palette_t); - palette->base.type = &displayio_palette_type; + displayio_palette_t *palette = mp_obj_malloc(displayio_palette_t, &displayio_palette_type); common_hal_displayio_palette_construct(palette, number_of_colors, false); if (number_of_colors > 1) { uint16_t palette_size = number_of_colors * sizeof(uint32_t); uint16_t palette_offset = 0xe + header_size; - uint32_t *palette_data = m_malloc(palette_size, false); + uint32_t *palette_data = m_malloc(palette_size); f_rewind(&self->file->fp); f_lseek(&self->file->fp, palette_offset); diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index c61b9ebc82025..8cd2da8973ffe 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -30,7 +30,7 @@ void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count, bool dither) { self->color_count = color_count; - self->colors = (_displayio_color_t *)m_malloc(color_count * sizeof(_displayio_color_t), false); + self->colors = (_displayio_color_t *)m_malloc(color_count * sizeof(_displayio_color_t)); self->dither = dither; } diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c index 1d6db5bd69308..25c5d1527a9b4 100644 --- a/shared-module/displayio/Shape.c +++ b/shared-module/displayio/Shape.c @@ -49,7 +49,7 @@ void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t widt } self->half_height = height; - self->data = m_malloc(height * sizeof(uint32_t), false); + self->data = m_malloc(height * sizeof(uint32_t)); for (uint16_t i = 0; i < height; i++) { self->data[2 * i] = 0; diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index ea659200277b7..d1e2389c2377a 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -48,7 +48,7 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ } self->inline_tiles = true; } else { - self->tiles = (uint8_t *)m_malloc(total_tiles, false); + self->tiles = (uint8_t *)m_malloc(total_tiles); for (uint32_t i = 0; i < total_tiles; i++) { self->tiles[i] = default_tile; } diff --git a/shared-module/displayio/display_core.c b/shared-module/displayio/display_core.c index 8e6d51084e23e..2af9b19fdb0b5 100644 --- a/shared-module/displayio/display_core.c +++ b/shared-module/displayio/display_core.c @@ -378,7 +378,7 @@ void displayio_display_core_collect_ptrs(displayio_display_core_t *self) { bool displayio_display_core_fill_area(displayio_display_core_t *self, displayio_area_t *area, uint32_t *mask, uint32_t *buffer) { if (self->current_group != NULL) { - return displayio_group_fill_area(self->current_group,&self->colorspace, area, mask, buffer); + return displayio_group_fill_area(self->current_group, &self->colorspace, area, mask, buffer); } return false; } diff --git a/shared-module/gifio/GifWriter.c b/shared-module/gifio/GifWriter.c index c993a87d0a6a7..9167de75a038d 100644 --- a/shared-module/gifio/GifWriter.c +++ b/shared-module/gifio/GifWriter.c @@ -90,7 +90,7 @@ void shared_module_gifio_gifwriter_construct(gifio_gifwriter_t *self, mp_obj_t * size_t nblocks = (width * height + 125) / 126; self->size = nblocks * 128 + 4; - self->data = gc_alloc(self->size, 0, false); + self->data = m_malloc(self->size); self->cur = 0; self->error = 0; diff --git a/shared-module/gifio/OnDiskGif.c b/shared-module/gifio/OnDiskGif.c index 039e77cf4533c..3f021cb33e05d 100644 --- a/shared-module/gifio/OnDiskGif.c +++ b/shared-module/gifio/OnDiskGif.c @@ -181,8 +181,7 @@ void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_ int bpp = 16; if (use_palette == true) { - displayio_palette_t *palette = m_new_obj(displayio_palette_t); - palette->base.type = &displayio_palette_type; + displayio_palette_t *palette = mp_obj_malloc(displayio_palette_t, &displayio_palette_type); common_hal_displayio_palette_construct(palette, 256, false); self->palette = palette; bpp = 8; @@ -190,8 +189,7 @@ void common_hal_gifio_ondiskgif_construct(gifio_ondiskgif_t *self, pyb_file_obj_ self->palette = NULL; } - displayio_bitmap_t *bitmap = m_new_obj(displayio_bitmap_t); - bitmap->base.type = &displayio_bitmap_type; + displayio_bitmap_t *bitmap = mp_obj_malloc(displayio_bitmap_t, &displayio_bitmap_type); common_hal_displayio_bitmap_construct(bitmap, self->gif.iCanvasWidth, self->gif.iCanvasHeight, bpp); self->bitmap = bitmap; diff --git a/shared-module/ipaddress/__init__.c b/shared-module/ipaddress/__init__.c index 9d98c0eb7c8bf..4801500f74f35 100644 --- a/shared-module/ipaddress/__init__.c +++ b/shared-module/ipaddress/__init__.c @@ -28,8 +28,7 @@ #include "shared-bindings/ipaddress/IPv4Address.h" mp_obj_t common_hal_ipaddress_new_ipv4address(uint32_t value) { - ipaddress_ipv4address_obj_t *self = m_new_obj(ipaddress_ipv4address_obj_t); - self->base.type = &ipaddress_ipv4address_type; + ipaddress_ipv4address_obj_t *self = mp_obj_malloc(ipaddress_ipv4address_obj_t, &ipaddress_ipv4address_type); common_hal_ipaddress_ipv4address_construct(self, (uint8_t *)&value, 4); return MP_OBJ_FROM_PTR(self); } diff --git a/shared-module/keypad/EventQueue.c b/shared-module/keypad/EventQueue.c index eeeceb78cfcfe..36d7d9dff5f41 100644 --- a/shared-module/keypad/EventQueue.c +++ b/shared-module/keypad/EventQueue.c @@ -35,7 +35,7 @@ void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events) { // Event queue is 16-bit values. - ringbuf_alloc(&self->encoded_events, max_events * (sizeof(uint16_t) + sizeof(mp_obj_t)), false); + ringbuf_alloc(&self->encoded_events, max_events * (sizeof(uint16_t) + sizeof(mp_obj_t))); self->overflowed = false; } @@ -53,8 +53,7 @@ bool common_hal_keypad_eventqueue_get_into(keypad_eventqueue_obj_t *self, keypad } mp_obj_t common_hal_keypad_eventqueue_get(keypad_eventqueue_obj_t *self) { - keypad_event_obj_t *event = m_new_obj(keypad_event_obj_t); - event->base.type = &keypad_event_type; + keypad_event_obj_t *event = mp_obj_malloc(keypad_event_obj_t, &keypad_event_type); bool result = common_hal_keypad_eventqueue_get_into(self, event); if (result) { return event; diff --git a/shared-module/keypad/KeyMatrix.c b/shared-module/keypad/KeyMatrix.c index b2520521cca04..df5c55b3f7c9a 100644 --- a/shared-module/keypad/KeyMatrix.c +++ b/shared-module/keypad/KeyMatrix.c @@ -53,8 +53,8 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint mp_obj_t row_dios[num_row_pins]; for (size_t row = 0; row < num_row_pins; row++) { - digitalio_digitalinout_obj_t *dio = m_new_obj(digitalio_digitalinout_obj_t); - dio->base.type = &digitalio_digitalinout_type; + digitalio_digitalinout_obj_t *dio = + mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(dio, row_pins[row]); common_hal_digitalio_digitalinout_switch_to_input(dio, columns_to_anodes ? PULL_UP : PULL_DOWN); row_dios[row] = dio; @@ -63,7 +63,8 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint mp_obj_t column_dios[num_column_pins]; for (size_t column = 0; column < num_column_pins; column++) { - digitalio_digitalinout_obj_t *dio = m_new_obj(digitalio_digitalinout_obj_t); + digitalio_digitalinout_obj_t *dio = + mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); dio->base.type = &digitalio_digitalinout_type; common_hal_digitalio_digitalinout_construct(dio, column_pins[column]); common_hal_digitalio_digitalinout_switch_to_input(dio, columns_to_anodes ? PULL_UP : PULL_DOWN); @@ -71,8 +72,8 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint } self->column_digitalinouts = mp_obj_new_tuple(num_column_pins, column_dios); - self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * num_row_pins * num_column_pins, false, false); - self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * num_row_pins * num_column_pins, false, false); + self->currently_pressed = (bool *)m_malloc(sizeof(bool) * num_row_pins * num_column_pins); + self->previously_pressed = (bool *)m_malloc(sizeof(bool) * num_row_pins * num_column_pins); self->columns_to_anodes = columns_to_anodes; self->funcs = &keymatrix_funcs; diff --git a/shared-module/keypad/Keys.c b/shared-module/keypad/Keys.c index d74a3ab859f7a..22ad7cc7fb87a 100644 --- a/shared-module/keypad/Keys.c +++ b/shared-module/keypad/Keys.c @@ -48,8 +48,8 @@ void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pin mp_obj_t dios[num_pins]; for (size_t i = 0; i < num_pins; i++) { - digitalio_digitalinout_obj_t *dio = m_new_obj(digitalio_digitalinout_obj_t); - dio->base.type = &digitalio_digitalinout_type; + digitalio_digitalinout_obj_t *dio = + mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(dio, pins[i]); if (pull) { common_hal_digitalio_digitalinout_set_pull(dio, value_when_pressed ? PULL_DOWN : PULL_UP); @@ -58,8 +58,8 @@ void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pin } self->digitalinouts = mp_obj_new_tuple(num_pins, dios); - self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * num_pins, false, false); - self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * num_pins, false, false); + self->currently_pressed = (bool *)m_malloc(sizeof(bool) * num_pins); + self->previously_pressed = (bool *)m_malloc(sizeof(bool) * num_pins); self->value_when_pressed = value_when_pressed; self->funcs = &keys_funcs; diff --git a/shared-module/keypad/ShiftRegisterKeys.c b/shared-module/keypad/ShiftRegisterKeys.c index 44a7e3323a72a..028b6aaf8007a 100644 --- a/shared-module/keypad/ShiftRegisterKeys.c +++ b/shared-module/keypad/ShiftRegisterKeys.c @@ -46,8 +46,8 @@ static keypad_scanner_funcs_t shiftregisterkeys_funcs = { void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_t *self, const mcu_pin_obj_t *clock_pin, mp_uint_t num_data_pins, const mcu_pin_obj_t *data_pins[], const mcu_pin_obj_t *latch_pin, bool value_to_latch, mp_uint_t num_key_counts, size_t key_counts[], bool value_when_pressed, mp_float_t interval, size_t max_events) { - digitalio_digitalinout_obj_t *clock = m_new_obj(digitalio_digitalinout_obj_t); - clock->base.type = &digitalio_digitalinout_type; + digitalio_digitalinout_obj_t *clock = + mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(clock, clock_pin); common_hal_digitalio_digitalinout_switch_to_output(clock, false, DRIVE_MODE_PUSH_PULL); self->clock = clock; @@ -72,10 +72,10 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ // Allocate a tuple object with the data pins self->data_pins = mp_obj_new_tuple(num_data_pins, dios); - self->key_counts = (mp_uint_t *)gc_alloc(sizeof(mp_uint_t) * num_key_counts, false, false); + self->key_counts = (mp_uint_t *)m_malloc(sizeof(mp_uint_t) * num_key_counts); self->num_key_counts = num_key_counts; - // copy to a gc_alloc() and on the fly record pin with largest Shift register + // copy to an m_malloc() and on the fly record pin with largest Shift register mp_uint_t max = 0; for (mp_uint_t i = 0; i < self->num_key_counts; i++) { diff --git a/shared-module/keypad/__init__.c b/shared-module/keypad/__init__.c index d2f5521a25a22..68cde559fb106 100644 --- a/shared-module/keypad/__init__.c +++ b/shared-module/keypad/__init__.c @@ -101,13 +101,12 @@ void keypad_deregister_scanner(keypad_scanner_obj_t *scanner) { void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, size_t max_events) { size_t key_count = common_hal_keypad_generic_get_key_count(self); - self->currently_pressed = (bool *)gc_alloc(sizeof(bool) * key_count, false, false); - self->previously_pressed = (bool *)gc_alloc(sizeof(bool) * key_count, false, false); + self->currently_pressed = (bool *)m_malloc(sizeof(bool) * key_count); + self->previously_pressed = (bool *)m_malloc(sizeof(bool) * key_count); self->interval_ticks = (mp_uint_t)(interval * 1024); // interval * 1000 * (1024/1000) - keypad_eventqueue_obj_t *events = m_new_obj(keypad_eventqueue_obj_t); - events->base.type = &keypad_eventqueue_type; + keypad_eventqueue_obj_t *events = mp_obj_malloc(keypad_eventqueue_obj_t, &keypad_eventqueue_type); common_hal_keypad_eventqueue_construct(events, max_events); self->events = events; diff --git a/shared-module/msgpack/__init__.c b/shared-module/msgpack/__init__.c index 3a34731d77146..27416a29fd841 100644 --- a/shared-module/msgpack/__init__.c +++ b/shared-module/msgpack/__init__.c @@ -385,8 +385,7 @@ STATIC mp_obj_t unpack_ext(msgpack_stream_t *s, size_t size, mp_obj_t ext_hook) if (ext_hook != mp_const_none) { return mp_call_function_2(ext_hook, MP_OBJ_NEW_SMALL_INT(code), data); } else { - mod_msgpack_extype_obj_t *o = m_new_obj(mod_msgpack_extype_obj_t); - o->base.type = &mod_msgpack_exttype_type; + mod_msgpack_extype_obj_t *o = mp_obj_malloc(mod_msgpack_extype_obj_t, &mod_msgpack_exttype_type); o->code = code; o->data = data; return MP_OBJ_FROM_PTR(o); diff --git a/shared-module/os/getenv.c b/shared-module/os/getenv.c index 76cbf48daebc1..7b102fd3e50b4 100644 --- a/shared-module/os/getenv.c +++ b/shared-module/os/getenv.c @@ -316,7 +316,7 @@ STATIC os_getenv_err_t os_getenv_buf_terminated(const char *key, char *value, si STATIC void print_dont_raise(const mp_obj_type_t *exc_type, const compressed_string_t *fmt, ...) { va_list argptr; - va_start(argptr,fmt); + va_start(argptr, fmt); mp_vcprintf(&mp_plat_print, fmt, argptr); mp_printf(&mp_plat_print, "\n"); va_end(argptr); diff --git a/shared-module/qrio/quirc_alloc.h b/shared-module/qrio/quirc_alloc.h index b01fac5bfb910..a669dcea310f2 100644 --- a/shared-module/qrio/quirc_alloc.h +++ b/shared-module/qrio/quirc_alloc.h @@ -7,8 +7,8 @@ #error Requires MICROPY_GC_CONSERVATIVE_CLEAR #endif -#define QUIRC_MALLOC(x) gc_alloc((x), 0, false) -#define QUIRC_CALLOC(x,y) gc_alloc((x) * (y), 0, false) +#define QUIRC_MALLOC(x) m_malloc((x)) +#define QUIRC_CALLOC(x, y) m_malloc((x) * (y)) #define QUIRC_FREE(x) gc_free((x)) #define QUIRC_SMALL_STACK (1) diff --git a/shared-module/synthio/Math.c b/shared-module/synthio/Math.c index f1a67d29b52cb..c975dfbf066a7 100644 --- a/shared-module/synthio/Math.c +++ b/shared-module/synthio/Math.c @@ -112,9 +112,9 @@ mp_float_t common_hal_synthio_math_tick(mp_obj_t self_in) { } return c; case OP_MIN: - return MIN(a,MIN(b,c)); + return MIN(a, MIN(b, c)); case OP_MAX: - return MAX(a,MAX(b,c)); + return MAX(a, MAX(b, c)); case OP_ABS: break; } diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c index 4929240d3bd81..c4f5b2f9b88e3 100644 --- a/shared-module/synthio/__init__.c +++ b/shared-module/synthio/__init__.c @@ -328,7 +328,7 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t continue; } - uint16_t loudness[2] = {synth->envelope_state[chan].level,synth->envelope_state[chan].level}; + uint16_t loudness[2] = {synth->envelope_state[chan].level, synth->envelope_state[chan].level}; if (!synth_note_into_buffer(synth, chan, tmp_buffer32, dur, loudness)) { // for some other reason, such as being above nyquist, note @@ -396,8 +396,8 @@ void synthio_synth_init(synthio_synth_t *synth, uint32_t sample_rate, int channe synthio_synth_parse_waveform(&synth->waveform_bufinfo, waveform_obj); mp_arg_validate_int_range(channel_count, 1, 2, MP_QSTR_channel_count); synth->buffer_length = SYNTHIO_MAX_DUR * SYNTHIO_BYTES_PER_SAMPLE * channel_count; - synth->buffers[0] = m_malloc(synth->buffer_length, false); - synth->buffers[1] = m_malloc(synth->buffer_length, false); + synth->buffers[0] = m_malloc(synth->buffer_length); + synth->buffers[1] = m_malloc(synth->buffer_length); synth->channel_count = channel_count; synth->other_channel = -1; synth->waveform_obj = waveform_obj; diff --git a/shared-module/touchio/TouchIn.c b/shared-module/touchio/TouchIn.c index 35dd56a6e4984..bc98fa05f761a 100644 --- a/shared-module/touchio/TouchIn.c +++ b/shared-module/touchio/TouchIn.c @@ -71,8 +71,7 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin) { common_hal_mcu_pin_claim(pin); - self->digitalinout = m_new_obj(digitalio_digitalinout_obj_t); - self->digitalinout->base.type = &digitalio_digitalinout_type; + self->digitalinout = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(self->digitalinout, pin); diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index 6f530bfef8aff..869179495559b 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -198,7 +198,7 @@ void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t re // Copy the raw descriptor bytes into a heap obj. We don't keep the Python descriptor object. - uint8_t *descriptor_bytes = gc_alloc(bufinfo.len, false, false); + uint8_t *descriptor_bytes = gc_alloc(bufinfo.len, false); memcpy(descriptor_bytes, bufinfo.buf, bufinfo.len); self->report_descriptor = descriptor_bytes; @@ -255,12 +255,12 @@ void usb_hid_device_create_report_buffers(usb_hid_device_obj_t *self) { // which is an unusual case. Normally we can just pass the data directly with tud_hid_report(). self->in_report_buffers[i] = self->in_report_lengths[i] > 0 - ? gc_alloc(self->in_report_lengths[i], false, true /*long-lived*/) + ? gc_alloc(self->in_report_lengths[i], false) : NULL; self->out_report_buffers[i] = self->out_report_lengths[i] > 0 - ? gc_alloc(self->out_report_lengths[i], false, true /*long-lived*/) + ? gc_alloc(self->out_report_lengths[i], false) : NULL; } memset(self->out_report_buffers_updated, 0, sizeof(self->out_report_buffers_updated)); diff --git a/shared/readline/readline.c b/shared/readline/readline.c index d8602a9e2827e..9e1e904417602 100644 --- a/shared/readline/readline.c +++ b/shared/readline/readline.c @@ -42,6 +42,10 @@ #define READLINE_HIST_SIZE (MP_ARRAY_SIZE(MP_STATE_PORT(readline_hist))) +// flags for readline_t.auto_indent_state +#define AUTO_INDENT_ENABLED (0x01) +#define AUTO_INDENT_JUST_ADDED (0x02) + enum { ESEQ_NONE, ESEQ_ESC, ESEQ_ESC_BRACKET, ESEQ_ESC_BRACKET_DIGIT, ESEQ_ESC_O }; void readline_init0(void) { @@ -105,6 +109,9 @@ typedef struct _readline_t { size_t cursor_pos; uint8_t utf8_cont_chars; char escape_seq_buf[1]; + #if MICROPY_REPL_AUTO_INDENT + uint8_t auto_indent_state; + #endif const char *prompt; } readline_t; @@ -248,11 +255,37 @@ int readline_process_char(int c) { redraw_step_back = nspace; redraw_from_cursor = true; } + #if MICROPY_REPL_AUTO_INDENT + } else if ((rl.auto_indent_state & AUTO_INDENT_JUST_ADDED) && (c == 9 || c == ' ')) { + // tab/space after auto-indent: disable auto-indent + // - if it's a tab then leave existing indent + // - if it's a space then remove 3 spaces from existing indent + rl.auto_indent_state = 0; + if (c == ' ') { + redraw_step_back = 3; + vstr_cut_tail_bytes(rl.line, 3); + } + #endif #if MICROPY_HELPER_REPL } else if (c == 9) { // tab magic const char *compl_str; - size_t compl_len = mp_repl_autocomplete(rl.line->buf + rl.orig_line_len, rl.cursor_pos - rl.orig_line_len, &mp_plat_print, &compl_str); + size_t compl_len; + if (vstr_len(rl.line) != 0 && unichar_isspace(vstr_str(rl.line)[rl.cursor_pos - 1])) { + // expand tab to 4 spaces if it follows whitespace: + // - includes the case of additional indenting + // - includes the case of indenting the start of a line that's not the first line, + // because a newline will be the previous character + // - doesn't include the case when at the start of the first line, because we still + // want to use auto-complete there + compl_str = " "; + compl_len = 4; + } else { + // try to auto-complete a word + const char *cur_line_buf = vstr_str(rl.line) + rl.orig_line_len; + size_t cur_line_len = rl.cursor_pos - rl.orig_line_len; + compl_len = mp_repl_autocomplete(cur_line_buf, cur_line_len, &mp_plat_print, &compl_str); + } if (compl_len == 0) { // no match } else if (compl_len == (size_t)(-1)) { @@ -504,11 +537,18 @@ int readline_process_char(int c) { rl.cursor_pos += redraw_step_forward; } + #if MICROPY_REPL_AUTO_INDENT + rl.auto_indent_state &= ~AUTO_INDENT_JUST_ADDED; + #endif + return -1; } #if MICROPY_REPL_AUTO_INDENT STATIC void readline_auto_indent(void) { + if (!(rl.auto_indent_state & AUTO_INDENT_ENABLED)) { + return; + } vstr_t *line = rl.line; if (line->len > 1 && line->buf[line->len - 1] == '\n') { int i; @@ -544,6 +584,7 @@ STATIC void readline_auto_indent(void) { vstr_add_strn(line, " ", 4); mp_hal_stdout_tx_strn(" ", 4); rl.cursor_pos += 4; + rl.auto_indent_state |= AUTO_INDENT_JUST_ADDED; } } } @@ -569,6 +610,10 @@ void readline_init(vstr_t *line, const char *prompt) { rl.prompt = prompt; mp_hal_stdout_tx_str(prompt); #if MICROPY_REPL_AUTO_INDENT + if (vstr_len(line) == 0) { + // start with auto-indent enabled + rl.auto_indent_state = AUTO_INDENT_ENABLED; + } readline_auto_indent(); #endif } diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index aeb92f59d3b6b..0717bfc6a887a 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George + * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,7 +33,6 @@ #include "py/runtime.h" #include "py/repl.h" #include "py/gc.h" -#include "py/gc_long_lived.h" #include "py/frozenmod.h" #include "py/mphal.h" #if MICROPY_HW_ENABLE_USB @@ -93,7 +92,11 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input #if MICROPY_MODULE_FROZEN_MPY if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) { // source is a raw_code object, create the function - module_fun = mp_make_function_from_raw_code(source, MP_OBJ_NULL, MP_OBJ_NULL); + const mp_frozen_module_t *frozen = source; + mp_module_context_t *ctx = m_new_obj(mp_module_context_t); + ctx->module.globals = mp_globals_get(); + ctx->constants = frozen->constants; + module_fun = mp_make_function_from_raw_code(frozen->rc, ctx, NULL); } else #endif { @@ -111,22 +114,15 @@ STATIC int parse_compile_execute(const void *source, mp_parse_input_kind_t input } // source is a lexer, parse and compile the script qstr source_name = lex->source_name; - if (input_kind == MP_PARSE_FILE_INPUT) { - mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); - } mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); module_fun = mp_compile(&parse_tree, source_name, exec_flags & EXEC_FLAG_IS_REPL); - // Clear the parse tree because it has a heap pointer we don't need anymore. - *((uint32_t volatile *)&parse_tree.chunk) = 0; #else mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("script compilation not supported")); #endif } - // If the code was loaded from a file it's likely to be running for a while so we'll long - // live it and collect any garbage before running. + // If the code was loaded from a file, collect any garbage before running. if (input_kind == MP_PARSE_FILE_INPUT) { - module_fun = make_obj_long_lived(module_fun, 6); gc_collect(); } } @@ -493,7 +489,7 @@ STATIC int pyexec_friendly_repl_process_char(int c) { vstr_add_byte(MP_STATE_VM(repl_line), '\n'); repl.cont_line = true; - readline_note_newline("... "); + readline_note_newline(mp_repl_get_ps2()); return 0; } else { @@ -514,7 +510,7 @@ STATIC int pyexec_friendly_repl_process_char(int c) { if (mp_repl_continue_with_input(vstr_null_terminated_str(MP_STATE_VM(repl_line)))) { vstr_add_byte(MP_STATE_VM(repl_line), '\n'); - readline_note_newline("... "); + readline_note_newline(mp_repl_get_ps2()); return 0; } @@ -528,7 +524,7 @@ STATIC int pyexec_friendly_repl_process_char(int c) { vstr_reset(MP_STATE_VM(repl_line)); repl.cont_line = false; repl.paste_mode = false; - readline_init(MP_STATE_VM(repl_line), ">>> "); + readline_init(MP_STATE_VM(repl_line), mp_repl_get_ps1()); return 0; } } @@ -725,7 +721,7 @@ int pyexec_friendly_repl(void) { // got a line with non-zero length, see if it needs continuing while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) { vstr_add_byte(&line, '\n'); - ret = readline(&line, "... "); + ret = readline(&line, mp_repl_get_ps2()); if (ret == CHAR_CTRL_C) { // cancel everything mp_hal_stdout_tx_str("\r\n"); diff --git a/shared/timeutils/timeutils.h b/shared/timeutils/timeutils.h index bfed13d3a4c17..f82e57fe96149 100644 --- a/shared/timeutils/timeutils.h +++ b/shared/timeutils/timeutils.h @@ -69,6 +69,7 @@ static inline uint64_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t static inline uint64_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { + // TODO this will give incorrect results for dates before 2000/1/1 return timeutils_seconds_since_2000(year, month, date, hour, minute, second) + TIMEUTILS_SECONDS_1970_TO_2000; } diff --git a/supervisor/linker.h b/supervisor/linker.h index 2d88812da4fc4..2106e167cfb5c 100644 --- a/supervisor/linker.h +++ b/supervisor/linker.h @@ -33,7 +33,7 @@ #define PLACE_IN_DTCM_DATA(name) name __attribute__((section(".dtcm_data." #name))) #define PLACE_IN_DTCM_BSS(name) name __attribute__((section(".dtcm_bss." #name))) // Don't inline ITCM functions because that may pull them out of ITCM into other sections. -#define PLACE_IN_ITCM(name) __attribute__((section(".itcm." #name),noinline,aligned(4))) name +#define PLACE_IN_ITCM(name) __attribute__((section(".itcm." #name), noinline, aligned(4))) name #else #define PLACE_IN_DTCM_DATA(name) name #define PLACE_IN_DTCM_BSS(name) name diff --git a/supervisor/shared/background_callback.c b/supervisor/shared/background_callback.c index 17fed37e223ba..6cb14b0cf1bc1 100644 --- a/supervisor/shared/background_callback.c +++ b/supervisor/shared/background_callback.c @@ -72,7 +72,7 @@ void PLACE_IN_ITCM(background_callback_add)(background_callback_t * cb, backgrou background_callback_add_core(cb); } -bool inline background_callback_pending(void) { +inline bool background_callback_pending(void) { return callback_head != NULL; } diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index ce7d78c42c33e..93069b271757b 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -214,7 +214,7 @@ mp_obj_list_t splash_children = { .items = members, }; #else -mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_status_bar_text_grid,}; +mp_obj_t members[] = { &supervisor_terminal_scroll_area_text_grid, &supervisor_terminal_status_bar_text_grid, }; mp_obj_list_t splash_children = { .base = {.type = &mp_type_list }, .alloc = 2, diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c index f72518ac50037..8d6938713dcfc 100644 --- a/supervisor/shared/external_flash/external_flash.c +++ b/supervisor/shared/external_flash/external_flash.c @@ -371,7 +371,7 @@ static bool allocate_ram_cache(void) { return false; } - MP_STATE_VM(flash_ram_cache) = m_malloc_maybe(blocks_per_sector * pages_per_block * sizeof(uint32_t), false); + MP_STATE_VM(flash_ram_cache) = m_malloc_maybe(blocks_per_sector * pages_per_block * sizeof(uint32_t)); if (MP_STATE_VM(flash_ram_cache) == NULL) { return false; } @@ -382,7 +382,7 @@ static bool allocate_ram_cache(void) { bool success = true; for (i = 0; i < blocks_per_sector; i++) { for (j = 0; j < pages_per_block; j++) { - uint8_t *page_cache = m_malloc_maybe(SPI_FLASH_PAGE_SIZE, false); + uint8_t *page_cache = m_malloc_maybe(SPI_FLASH_PAGE_SIZE); if (page_cache == NULL) { success = false; break; diff --git a/supervisor/shared/memory.c b/supervisor/shared/memory.c index ec0b27a9a61be..7420b2b0b894e 100644 --- a/supervisor/shared/memory.c +++ b/supervisor/shared/memory.c @@ -212,7 +212,7 @@ static supervisor_allocation_node *allocate_memory_node(uint32_t length, bool hi if (!node) { // 4. GC allocation? if (movable && gc_alloc_possible()) { - node = m_malloc_maybe(sizeof(supervisor_allocation_node) + length, true); + node = m_malloc_maybe(sizeof(supervisor_allocation_node) + length); if (node) { node->next = MP_STATE_VM(first_embedded_allocation); MP_STATE_VM(first_embedded_allocation) = node; diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 0ab97fc9a96cd..134952ca7fc97 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -127,7 +127,7 @@ void PLACE_IN_ITCM(safe_mode_on_next_reset)(safe_mode_t reason) { } // Don't inline this so it's easy to break on it from GDB. -void __attribute__((noinline,)) PLACE_IN_ITCM(reset_into_safe_mode)(safe_mode_t reason) { +void __attribute__((noinline, )) PLACE_IN_ITCM(reset_into_safe_mode)(safe_mode_t reason) { if (_safe_mode > SAFE_MODE_BROWNOUT && reason > SAFE_MODE_BROWNOUT) { while (true) { // This very bad because it means running in safe mode didn't save us. Only ignore brownout diff --git a/supervisor/shared/translate/translate.c b/supervisor/shared/translate/translate.c index b07aa584caa89..fced90f058b43 100644 --- a/supervisor/shared/translate/translate.c +++ b/supervisor/shared/translate/translate.c @@ -31,7 +31,7 @@ #include #ifndef NO_QSTR -#include "genhdr/compression.generated.h" +#include "genhdr/compressed_translations.generated.h" #endif #include "py/misc.h" diff --git a/supervisor/shared/translate/translate.h b/supervisor/shared/translate/translate.h index 8bb343cabe44a..8779fb6310904 100644 --- a/supervisor/shared/translate/translate.h +++ b/supervisor/shared/translate/translate.h @@ -33,9 +33,7 @@ #include "supervisor/shared/translate/compressed_string.h" // Map MicroPython's error messages to our translations. -#if defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME -#define MP_ERROR_TEXT(x) (x) -#else +#if !defined(MICROPY_ENABLE_DYNRUNTIME) || !MICROPY_ENABLE_DYNRUNTIME #define MP_ERROR_TEXT(x) translate(x) #endif diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 374edf1310e96..866a7f66cb0e2 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -85,6 +85,8 @@ else SRC_SUPERVISOR += supervisor/qspi_flash.c supervisor/shared/external_flash/qspi_flash.c endif +OBJ_EXTRA_ORDER_DEPS += $(HEADER_BUILD)/devices.h +SRC_QSTR += $(HEADER_BUILD)/devices.h $(HEADER_BUILD)/devices.h : ../../supervisor/shared/external_flash/devices.h.jinja ../../tools/gen_nvm_devices.py | $(HEADER_BUILD) $(STEPECHO) "GEN $@" $(Q)install -d $(BUILD)/genhdr @@ -226,7 +228,7 @@ endif USB_HIGHSPEED ?= 0 CFLAGS += -DUSB_HIGHSPEED=$(USB_HIGHSPEED) -$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compression.generated.h +$(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compressed_translations.generated.h CIRCUITPY_DISPLAY_FONT ?= "../../tools/fonts/ter-u12n.bdf" diff --git a/tests/basics/builtin_enumerate.py b/tests/basics/builtin_enumerate.py index 29b1dd46c40ea..fcbf86976726c 100644 --- a/tests/basics/builtin_enumerate.py +++ b/tests/basics/builtin_enumerate.py @@ -1,3 +1,9 @@ +try: + enumerate +except: + print("SKIP") + raise SystemExit + print(list(enumerate([]))) print(list(enumerate([1, 2, 3]))) print(list(enumerate([1, 2, 3], 5))) diff --git a/tests/basics/class_contains.py b/tests/basics/class_contains.py index b6dd3661cde90..5fdb1db4c0423 100644 --- a/tests/basics/class_contains.py +++ b/tests/basics/class_contains.py @@ -21,3 +21,27 @@ def __contains__(self, key): print(1 in b) print(2 in b) print(3 in b) + + +class C: + def __contains__(self, arg): + return arg + + +print(C().__contains__(0)) +print(C().__contains__(1)) +print(C().__contains__('')) +print(C().__contains__('foo')) +print(C().__contains__(None)) + +print(0 in C()) +print(1 in C()) +print('' in C()) +print('foo' in C()) +print(None in C()) + +print(0 not in C()) +print(1 not in C()) +print('' not in C()) +print('foo' not in C()) +print(None not in C()) diff --git a/tests/basics/errno1.py.exp b/tests/basics/errno1.py.exp index ac3619161f6a7..594486b0f9bec 100644 --- a/tests/basics/errno1.py.exp +++ b/tests/basics/errno1.py.exp @@ -3,4 +3,4 @@ [Errno error: details ( , 'details', 'more details') 9999 -uerrno +errno diff --git a/tests/basics/fun_calldblstar4.py b/tests/basics/fun_calldblstar4.py new file mode 100644 index 0000000000000..acb332a8c23bb --- /dev/null +++ b/tests/basics/fun_calldblstar4.py @@ -0,0 +1,33 @@ +# test calling a function with multiple **args + + +def f(a, b=None, c=None): + print(a, b, c) + + +f(**{"a": 1}, **{"b": 2}) +f(**{"a": 1}, **{"b": 2}, c=3) +f(**{"a": 1}, b=2, **{"c": 3}) + +try: + f(1, **{"b": 2}, **{"b": 3}) +except TypeError: + print("TypeError") + +# test calling a method with multiple **args + + +class A: + def f(self, a, b=None, c=None): + print(a, b, c) + + +a = A() +a.f(**{"a": 1}, **{"b": 2}) +a.f(**{"a": 1}, **{"b": 2}, c=3) +a.f(**{"a": 1}, b=2, **{"c": 3}) + +try: + a.f(1, **{"b": 2}, **{"b": 3}) +except TypeError: + print("TypeError") diff --git a/tests/basics/fun_callstar.py b/tests/basics/fun_callstar.py index a27a288a3c2be..53d2ece3e138e 100644 --- a/tests/basics/fun_callstar.py +++ b/tests/basics/fun_callstar.py @@ -3,10 +3,16 @@ def foo(a, b, c): print(a, b, c) +foo(*(), 1, 2, 3) +foo(*(1,), 2, 3) +foo(*(1, 2), 3) foo(*(1, 2, 3)) foo(1, *(2, 3)) foo(1, 2, *(3,)) foo(1, 2, 3, *()) +foo(*(1,), 2, *(3,)) +foo(*(1, 2), *(3,)) +foo(*(1,), *(2, 3)) # Another sequence type foo(1, 2, *[100]) @@ -29,10 +35,16 @@ def foo(self, a, b, c): print(a, b, c) a = A() +a.foo(*(), 1, 2, 3) +a.foo(*(1,), 2, 3) +a.foo(*(1, 2), 3) a.foo(*(1, 2, 3)) a.foo(1, *(2, 3)) a.foo(1, 2, *(3,)) a.foo(1, 2, 3, *()) +a.foo(*(1,), 2, *(3,)) +a.foo(*(1, 2), *(3,)) +a.foo(*(1,), *(2, 3)) # Another sequence type a.foo(1, 2, *[100]) diff --git a/tests/basics/fun_callstardblstar.py b/tests/basics/fun_callstardblstar.py index f2fd29107e270..f395df3333ded 100644 --- a/tests/basics/fun_callstardblstar.py +++ b/tests/basics/fun_callstardblstar.py @@ -6,6 +6,11 @@ def f(a, b, c, d): f(*(1, 2), **{'c':3, 'd':4}) f(*(1, 2), **{['c', 'd'][i]:(3 + i) for i in range(2)}) +try: + eval("f(**{'a': 1}, *(2, 3, 4))") +except SyntaxError: + print("SyntaxError") + # test calling a method with *tuple and **dict class A: @@ -15,3 +20,20 @@ def f(self, a, b, c, d): a = A() a.f(*(1, 2), **{'c':3, 'd':4}) a.f(*(1, 2), **{['c', 'd'][i]:(3 + i) for i in range(2)}) + +try: + eval("a.f(**{'a': 1}, *(2, 3, 4))") +except SyntaxError: + print("SyntaxError") + + +# coverage test for arg allocation corner case + +def f2(*args, **kwargs): + print(len(args), len(kwargs)) + + +f2(*iter(range(4)), **{'a': 1}) + +# case where *args is not a tuple/list and takes up most of the memory allocated for **kwargs +f2(*iter(range(100)), **{str(i): i for i in range(100)}) diff --git a/tests/basics/fun_kwvarargs.py b/tests/basics/fun_kwvarargs.py index bdc10fcf14d8c..e9fd0720e94ff 100644 --- a/tests/basics/fun_kwvarargs.py +++ b/tests/basics/fun_kwvarargs.py @@ -23,3 +23,16 @@ def f4(*vargs, **kwargs): f4(*(1, 2)) f4(kw_arg=3) f4(*(1, 2), kw_arg=3) + + +# test evaluation order of arguments +def f5(*vargs, **kwargs): + print(vargs, kwargs) + + +def print_ret(x): + print(x) + return x + + +f5(*print_ret(["a", "b"]), kw_arg=print_ret(None)) diff --git a/tests/basics/nanbox_smallint.py b/tests/basics/nanbox_smallint.py new file mode 100644 index 0000000000000..167b196010a2d --- /dev/null +++ b/tests/basics/nanbox_smallint.py @@ -0,0 +1,43 @@ +# Test creating small integers without heap allocation in nan-boxing mode. + +import micropython + +try: + # Test for nan-box build by allocating a float while heap is locked. + # This should pass on nan-box builds. + micropython.heap_lock() + float(123) + micropython.heap_unlock() +except: + micropython.heap_unlock() + print("SKIP") + raise SystemExit + +# Check that nan-boxing uses 64-bit floats (eg it's not object representation C). +if float("1e100") == float("inf"): + print("SKIP") + raise SystemExit + +micropython.heap_lock() +print(int("0x80000000")) +micropython.heap_unlock() + +# This is the most positive small integer. +micropython.heap_lock() +print(int("0x3fffffffffff")) +micropython.heap_unlock() + +# This is the most negative small integer. +micropython.heap_lock() +print(int("-0x3fffffffffff") - 1) +micropython.heap_unlock() + +x = 1 +micropython.heap_lock() +print((x << 31) + 1) +micropython.heap_unlock() + +x = 1 +micropython.heap_lock() +print((x << 45) + 1) +micropython.heap_unlock() diff --git a/tests/basics/nanbox_smallint.py.exp b/tests/basics/nanbox_smallint.py.exp new file mode 100644 index 0000000000000..aad1f7b8b63c1 --- /dev/null +++ b/tests/basics/nanbox_smallint.py.exp @@ -0,0 +1,5 @@ +2147483648 +70368744177663 +-70368744177664 +2147483649 +35184372088833 diff --git a/tests/basics/python34.py b/tests/basics/python34.py index 4030db143c4d7..922234d22db93 100644 --- a/tests/basics/python34.py +++ b/tests/basics/python34.py @@ -6,27 +6,23 @@ print("SKIP") raise SystemExit -# from basics/fun_kwvarargs.py -# test evaluation order of arguments (in 3.4 it's backwards, 3.5 it's fixed) -def f4(*vargs, **kwargs): - print(vargs, kwargs) + def print_ret(x): print(x) return x -f4(*print_ret(['a', 'b']), kw_arg=print_ret(None)) # test evaluation order of dictionary key/value pair (in 3.4 it's backwards) {print_ret(1):print_ret(2)} + # from basics/syntaxerror.py def test_syntax(code): try: exec(code) except SyntaxError: print("SyntaxError") -test_syntax("f(*a, *b)") # can't have multiple * (in 3.5 we can) -test_syntax("f(**a, **b)") # can't have multiple ** (in 3.5 we can) -test_syntax("f(*a, b)") # can't have positional after * + + test_syntax("f(**a, b)") # can't have positional after ** test_syntax("() = []") # can't assign to empty tuple (in 3.6 we can) test_syntax("del ()") # can't delete empty tuple (in 3.6 we can) diff --git a/tests/basics/python34.py.exp b/tests/basics/python34.py.exp index 8480171307d14..a56c1a50b6996 100644 --- a/tests/basics/python34.py.exp +++ b/tests/basics/python34.py.exp @@ -1,14 +1,8 @@ -None -['a', 'b'] -('a', 'b') {'kw_arg': None} 2 1 SyntaxError SyntaxError SyntaxError -SyntaxError -SyntaxError -SyntaxError 3.4 3 4 IndexError('foo',) diff --git a/tests/basics/scope_class.py b/tests/basics/scope_class.py new file mode 100644 index 0000000000000..9c519695dc61a --- /dev/null +++ b/tests/basics/scope_class.py @@ -0,0 +1,77 @@ +# test scoping rules that involve a class + +# the inner A.method should be independent to the local function called method +def test1(): + def method(): + pass + + class A: + def method(): + pass + + print(hasattr(A, "method")) + print(hasattr(A(), "method")) + + +test1() + + +# the inner A.method is a closure and overrides the local function called method +def test2(): + def method(): + return "outer" + + class A: + nonlocal method + + def method(): + return "inner" + + print(hasattr(A, "method")) + print(hasattr(A(), "method")) + return method() # this is actually A.method + + +print(test2()) + + +# a class body will capture external variables by value (not by reference) +def test3(x): + class A: + local = x + + x += 1 + return x, A.local + + +print(test3(42)) + + +# assigning to a variable in a class will implicitly prevent it from closing over a variable +def test4(global_): + class A: + local = global_ # fetches outer global_ + global_ = "global2" # creates class attribute + + global_ += 1 # updates local variable + return global_, A.local, A.global_ + + +global_ = "global" +print(test4(42), global_) + + +# methods within a class can close over variables outside the class +def test5(x): + def closure(): + return x + + class A: + def method(): + return x, closure() + + closure = lambda: x + 1 # change it after A has been created + return A + + +print(test5(42).method()) diff --git a/tests/basics/string_format_cp310.py b/tests/basics/string_format_cp310.py new file mode 100644 index 0000000000000..77295330beab4 --- /dev/null +++ b/tests/basics/string_format_cp310.py @@ -0,0 +1,9 @@ +# Python 3.10+ functionality test for {} format string + +def test(fmt, *args): + print('{:8s}'.format(fmt) + '>' + fmt.format(*args) + '<') + +test("{:0s}", "ab") +test("{:06s}", "ab") +test("{:<06s}", "ab") +test("{:>06s}", "ab") diff --git a/tests/basics/string_format_cp310.py.exp b/tests/basics/string_format_cp310.py.exp new file mode 100644 index 0000000000000..1c26473d83761 --- /dev/null +++ b/tests/basics/string_format_cp310.py.exp @@ -0,0 +1,4 @@ +{:0s} >ab< +{:06s} >ab0000< +{:<06s} >ab0000< +{:>06s} >0000ab< diff --git a/tests/basics/string_format_error.py b/tests/basics/string_format_error.py index 708348d59fbf1..74dc6c52ed31e 100644 --- a/tests/basics/string_format_error.py +++ b/tests/basics/string_format_error.py @@ -1,7 +1,7 @@ # tests for errors in {} format string try: - '{0:0}'.format('zzz') + '{0:=}'.format('zzz') except (ValueError): print('ValueError') diff --git a/tests/basics/sys1.py b/tests/basics/sys1.py index 15f7771ef5563..c8dbfc3541e33 100644 --- a/tests/basics/sys1.py +++ b/tests/basics/sys1.py @@ -19,8 +19,8 @@ # Effectively skip subtests print(True) -if hasattr(sys.implementation, 'mpy'): - print(type(sys.implementation.mpy)) +if hasattr(sys.implementation, '_mpy'): + print(type(sys.implementation._mpy)) else: # Effectively skip subtests print(int) diff --git a/tests/basics/sys_tracebacklimit.py b/tests/basics/sys_tracebacklimit.py new file mode 100644 index 0000000000000..1ee638967f129 --- /dev/null +++ b/tests/basics/sys_tracebacklimit.py @@ -0,0 +1,78 @@ +# test sys.tracebacklimit + +try: + try: + import usys as sys + import uio as io + except ImportError: + import sys + import io +except ImportError: + print("SKIP") + raise SystemExit + +try: + sys.tracebacklimit = 1000 +except AttributeError: + print("SKIP") + raise SystemExit + +if hasattr(sys, "print_exception"): + print_exception = sys.print_exception +else: + import traceback + + print_exception = lambda e, f: traceback.print_exception(None, e, sys.exc_info()[2], file=f) + + +def print_exc(e): + buf = io.StringIO() + print_exception(e, buf) + s = buf.getvalue() + for l in s.split("\n"): + # Remove filename. + if l.startswith(" File "): + l = l.split('"') + print(l[0], l[2]) + # uPy and CPy tracebacks differ in that CPy prints a source line for + # each traceback entry. In this case, we know that offending line + # has 4-space indent, so filter it out. + elif not l.startswith(" "): + print(l) + + +def f0(): + raise ValueError("value") + + +def f1(): + f0() + + +def f2(): + f1() + + +def f3(): + f2() + + +def ftop(): + try: + f3() + except ValueError as er: + print_exc(er) + + +ftop() + +for limit in range(4, -2, -1): + print("limit", limit) + sys.tracebacklimit = limit + ftop() + + +# test deleting the attribute +print(hasattr(sys, "tracebacklimit")) +del sys.tracebacklimit +print(hasattr(sys, "tracebacklimit")) diff --git a/tests/basics/sys_tracebacklimit.py.exp b/tests/basics/sys_tracebacklimit.py.exp new file mode 100644 index 0000000000000..3647280584dde --- /dev/null +++ b/tests/basics/sys_tracebacklimit.py.exp @@ -0,0 +1,42 @@ +Traceback (most recent call last): + File , line 62, in ftop + File , line 57, in f3 + File , line 53, in f2 + File , line 49, in f1 + File , line 45, in f0 +ValueError: value + +limit 4 +Traceback (most recent call last): + File , line 62, in ftop + File , line 57, in f3 + File , line 53, in f2 + File , line 49, in f1 +ValueError: value + +limit 3 +Traceback (most recent call last): + File , line 62, in ftop + File , line 57, in f3 + File , line 53, in f2 +ValueError: value + +limit 2 +Traceback (most recent call last): + File , line 62, in ftop + File , line 57, in f3 +ValueError: value + +limit 1 +Traceback (most recent call last): + File , line 62, in ftop +ValueError: value + +limit 0 +ValueError: value + +limit -1 +ValueError: value + +True +False diff --git a/tests/cmdline/cmd_parsetree.py.exp b/tests/cmdline/cmd_parsetree.py.exp index 291cc7ecda82b..3049267c0b957 100644 --- a/tests/cmdline/cmd_parsetree.py.exp +++ b/tests/cmdline/cmd_parsetree.py.exp @@ -18,7 +18,7 @@ [ 8] literal \.\+ [ 9] \(rule\|expr_stmt\)(5) (n=2) id(d) - bytes(bytes) +[ 9] literal \.\+ [ 10] \(rule\|expr_stmt\)(5) (n=2) id(e) [ 10] literal \.\+ @@ -31,7 +31,7 @@ [ 13] \(rule\|expr_stmt\)(5) (n=2) id(h) [ 13] \(rule\|atom_expr_normal\)(44) (n=2) -[ 13] literal const(\.\+) +[ 13] literal const(\.\+)="fstring: '{}'" [ 13] \(rule\|atom_expr_trailers\)(142) (n=2) [ 13] \(rule\|trailer_period\)(50) (n=1) id(format) @@ -39,49 +39,52 @@ [ 13] \(rule\|arglist\)(164) (n=1) id(b) ---------------- -File cmdline/cmd_parsetree.py, code block '' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## +File cmdline/cmd_parsetree.py, code block '' (descriptor: \.\+, bytecode @\.\+ 62 bytes) +Raw bytecode (code_info_size=13, bytecode_size=49): + 20 16 01 60 27 22 23 24 24 24 24 24 25 2a 00 5f + 4b 04 16 04 42 3a 51 16 05 10 02 16 06 23 00 16 + 07 23 01 16 08 23 02 16 09 23 03 16 0a 22 80 7b + 16 0b 23 04 14 03 11 06 36 01 16 0c 51 63 arg names: (N_STATE 5) (N_EXC_STACK 0) bc=0 line=1 bc=0 line=4 - bc=9 line=5 - bc=12 line=6 - bc=16 line=7 - bc=22 line=8 - bc=27 line=9 - bc=32 line=10 - bc=37 line=11 - bc=42 line=12 - bc=48 line=13 + bc=7 line=5 + bc=9 line=6 + bc=12 line=7 + bc=16 line=8 + bc=20 line=9 + bc=24 line=10 + bc=28 line=11 + bc=32 line=12 + bc=37 line=13 00 BUILD_TUPLE 0 02 GET_ITER_STACK -03 FOR_ITER 12 -06 STORE_NAME i -09 JUMP 3 -12 LOAD_CONST_NONE -13 STORE_NAME a -16 LOAD_CONST_STRING 'str' -19 STORE_NAME b -22 LOAD_CONST_OBJ \.\+ -24 STORE_NAME c -27 LOAD_CONST_OBJ \.\+ -29 STORE_NAME d -32 LOAD_CONST_OBJ \.\+ -34 STORE_NAME e -37 LOAD_CONST_OBJ \.\+ -39 STORE_NAME f -42 LOAD_CONST_SMALL_INT 123 -45 STORE_NAME g -48 LOAD_CONST_OBJ \.\+ -50 LOAD_METHOD format -53 LOAD_NAME b -56 CALL_METHOD n=1 nkw=0 -58 STORE_NAME h -61 LOAD_CONST_NONE -62 RETURN_VALUE +03 FOR_ITER 9 +05 STORE_NAME i +07 JUMP 3 +09 LOAD_CONST_NONE +10 STORE_NAME a +12 LOAD_CONST_STRING 'str' +14 STORE_NAME b +16 LOAD_CONST_OBJ \.\+='a very long str that will not be interned' +18 STORE_NAME c +20 LOAD_CONST_OBJ \.\+=b'bytes' +22 STORE_NAME d +24 LOAD_CONST_OBJ \.\+=b'a very long bytes that will not be interned' +26 STORE_NAME e +28 LOAD_CONST_OBJ \.\+=123456789012345678901234567890 +30 STORE_NAME f +32 LOAD_CONST_SMALL_INT 123 +35 STORE_NAME g +37 LOAD_CONST_OBJ \.\+="fstring: '{}'" +39 LOAD_METHOD format +41 LOAD_NAME b +43 CALL_METHOD n=1 nkw=0 +45 STORE_NAME h +47 LOAD_CONST_NONE +48 RETURN_VALUE mem: total=\\d\+, current=\\d\+, peak=\\d\+ stack: \\d\+ out of \\d\+ GC: total: \\d\+, used: \\d\+, free: \\d\+ diff --git a/tests/cmdline/cmd_showbc.py b/tests/cmdline/cmd_showbc.py index a960c15c4a973..e5874f990ab90 100644 --- a/tests/cmdline/cmd_showbc.py +++ b/tests/cmdline/cmd_showbc.py @@ -40,7 +40,7 @@ def f(): # slice a = b[::] - # sequenc unpacking + # sequence unpacking a, b = c a, *a = a diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index c3dbfd74f8322..45a1d169b6197 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -1,50 +1,144 @@ -File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## +File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ 63 bytes) +Raw bytecode (code_info_size=18, bytecode_size=45): + 10 20 01 60 20 84 7d 64 60 88 07 64 60 69 20 62 + 64 20 32 00 16 05 32 01 16 05 81 2a 01 53 33 02 + 16 05 32 03 16 05 54 32 04 10 02 34 02 16 02 19 + 02 32 05 16 05 80 10 03 2a 01 1b 04 69 51 63 arg names: (N_STATE 3) (N_EXC_STACK 0) bc=0 line=1 -######## - bc=\\d\+ line=160 + bc=0 line=4 + bc=0 line=5 + bc=4 line=130 + bc=8 line=133 + bc=8 line=136 + bc=16 line=143 + bc=20 line=146 + bc=20 line=149 + bc=29 line=152 + bc=29 line=153 + bc=31 line=156 + bc=35 line=159 + bc=35 line=160 00 MAKE_FUNCTION \.\+ -\\d\+ STORE_NAME f -\\d\+ MAKE_FUNCTION \.\+ -\\d\+ STORE_NAME f -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ BUILD_TUPLE 1 -\\d\+ LOAD_NULL -\\d\+ MAKE_FUNCTION_DEFARGS \.\+ -\\d\+ STORE_NAME f -\\d\+ MAKE_FUNCTION \.\+ -\\d\+ STORE_NAME f -\\d\+ LOAD_BUILD_CLASS -\\d\+ MAKE_FUNCTION \.\+ -\\d\+ LOAD_CONST_STRING 'Class' -\\d\+ CALL_FUNCTION n=2 nkw=0 -\\d\+ STORE_NAME Class -\\d\+ DELETE_NAME Class -\\d\+ MAKE_FUNCTION \.\+ -\\d\+ STORE_NAME f -\\d\+ LOAD_CONST_SMALL_INT 0 -\\d\+ LOAD_CONST_STRING '*' -\\d\+ BUILD_TUPLE 1 -\\d\+ IMPORT_NAME 'sys' -\\d\+ IMPORT_STAR -\\d\+ LOAD_CONST_NONE -\\d\+ RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): +02 STORE_NAME f +04 MAKE_FUNCTION \.\+ +06 STORE_NAME f +08 LOAD_CONST_SMALL_INT 1 +09 BUILD_TUPLE 1 +11 LOAD_NULL +12 MAKE_FUNCTION_DEFARGS \.\+ +14 STORE_NAME f +16 MAKE_FUNCTION \.\+ +18 STORE_NAME f +20 LOAD_BUILD_CLASS +21 MAKE_FUNCTION \.\+ +23 LOAD_CONST_STRING 'Class' +25 CALL_FUNCTION n=2 nkw=0 +27 STORE_NAME Class +29 DELETE_NAME Class +31 MAKE_FUNCTION \.\+ +33 STORE_NAME f +35 LOAD_CONST_SMALL_INT 0 +36 LOAD_CONST_STRING '*' +38 BUILD_TUPLE 1 +40 IMPORT_NAME 'sys' +42 IMPORT_STAR +43 LOAD_CONST_NONE +44 RETURN_VALUE +File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 45\[46\] bytes) +Raw bytecode (code_info_size=8\[46\], bytecode_size=370): + a8 12 9\[bf\] 03 05 60 60 26 22 24 64 22 24 25 25 24 + 26 23 63 22 22 25 23 23 2f 6c 25 65 25 25 69 68 + 26 65 27 6a 62 20 23 62 2a 29 69 24 25 28 67 26 ######## -\.\+rg names: +\.\+81 63 +arg names: (N_STATE 22) (N_EXC_STACK 2) (INIT_CELL 14) (INIT_CELL 15) (INIT_CELL 16) bc=0 line=1 + bc=0 line=4 + bc=0 line=7 + bc=6 line=8 + bc=8 line=9 + bc=12 line=10 + bc=16 line=13 + bc=18 line=14 + bc=22 line=15 + bc=27 line=16 + bc=32 line=17 + bc=36 line=18 + bc=42 line=19 + bc=45 line=20 + bc=48 line=23 + bc=50 line=24 + bc=52 line=25 + bc=57 line=26 + bc=60 line=27 + bc=63 line=28 + bc=78 line=29 + bc=90 line=32 + bc=95 line=33 + bc=100 line=36 + bc=105 line=37 + bc=110 line=38 + bc=119 line=41 + bc=127 line=44 + bc=133 line=45 + bc=138 line=48 + bc=145 line=49 + bc=155 line=52 + bc=157 line=55 + bc=157 line=56 + bc=160 line=57 + bc=162 line=60 + bc=172 line=61 + bc=181 line=62 + bc=190 line=65 + bc=194 line=66 + bc=199 line=67 + bc=207 line=68 + bc=214 line=71 + bc=220 line=72 + bc=227 line=73 + bc=237 line=74 + bc=245 line=77 + bc=248 line=78 + bc=253 line=80 + bc=256 line=81 + bc=258 line=82 + bc=264 line=83 + bc=266 line=84 + bc=272 line=85 + bc=277 line=88 + bc=283 line=89 + bc=287 line=92 + bc=291 line=93 + bc=293 line=94 +######## + bc=301 line=96 + bc=308 line=98 + bc=311 line=99 + bc=313 line=100 + bc=315 line=101 ######## - bc=\\d\+ line=127 + bc=321 line=103 + bc=327 line=106 + bc=331 line=107 + bc=337 line=110 + bc=340 line=111 + bc=346 line=114 + bc=346 line=117 + bc=351 line=118 + bc=363 line=121 + bc=363 line=122 + bc=364 line=123 + bc=366 line=126 + bc=368 line=127 00 LOAD_CONST_NONE 01 LOAD_CONST_FALSE 02 BINARY_OP 27 __add__ @@ -59,267 +153,269 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): 15 STORE_FAST 0 16 LOAD_CONST_SMALL_INT 1 17 STORE_FAST 0 -18 LOAD_CONST_SMALL_INT 1 -19 LOAD_CONST_SMALL_INT 2 -20 BUILD_TUPLE 2 -22 STORE_DEREF 14 -24 LOAD_CONST_SMALL_INT 1 -25 LOAD_CONST_SMALL_INT 2 -26 BUILD_LIST 2 -28 STORE_FAST 1 -29 LOAD_CONST_SMALL_INT 1 -30 LOAD_CONST_SMALL_INT 2 -31 BUILD_SET 2 -33 STORE_FAST 2 -34 BUILD_MAP 0 -36 STORE_DEREF 15 -38 BUILD_MAP 1 -40 LOAD_CONST_SMALL_INT 2 -41 LOAD_CONST_SMALL_INT 1 -42 STORE_MAP -43 STORE_FAST 3 -44 LOAD_CONST_STRING 'a' -47 STORE_FAST 4 -48 LOAD_CONST_OBJ \.\+ -\\d\+ STORE_FAST 5 -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ STORE_FAST 6 -\\d\+ LOAD_CONST_SMALL_INT 2 -\\d\+ STORE_FAST 7 -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_DEREF 14 -58 BINARY_OP 27 __add__ -\\d\+ STORE_FAST 8 -\\d\+ LOAD_FAST 0 -\\d\+ UNARY_OP 1 __neg__ -\\d\+ STORE_FAST 9 -\\d\+ LOAD_FAST 0 -\\d\+ UNARY_OP 3 -\\d\+ STORE_FAST 10 -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_DEREF 14 -\\d\+ DUP_TOP -\\d\+ ROT_THREE -\\d\+ BINARY_OP 2 __eq__ -\\d\+ JUMP_IF_FALSE_OR_POP \\d\+ -\\d\+ LOAD_FAST 1 -\\d\+ BINARY_OP 2 __eq__ -\\d\+ JUMP \\d\+ -\\d\+ ROT_TWO -\\d\+ POP_TOP -\\d\+ STORE_FAST 10 -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_DEREF 14 -\\d\+ BINARY_OP 2 __eq__ -\\d\+ JUMP_IF_FALSE_OR_POP \\d\+ -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_FAST 1 -\\d\+ BINARY_OP 2 __eq__ -\\d\+ UNARY_OP 3 -\\d\+ STORE_FAST 10 -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_ATTR c -\\d\+ STORE_FAST 11 -\\d\+ LOAD_FAST 11 -\\d\+ LOAD_DEREF 14 -\\d\+ STORE_ATTR c -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_CONST_SMALL_INT 0 -\\d\+ LOAD_SUBSCR -\\d\+ STORE_FAST 12 -\\d\+ LOAD_FAST 12 -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_CONST_SMALL_INT 0 -\\d\+ STORE_SUBSCR -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_CONST_SMALL_INT 0 -\\d\+ DUP_TOP_TWO -\\d\+ LOAD_SUBSCR -\\d\+ LOAD_FAST 12 -\\d\+ BINARY_OP 14 __iadd__ -\\d\+ ROT_THREE -\\d\+ STORE_SUBSCR -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_CONST_NONE -\\d\+ LOAD_CONST_NONE -\\d\+ BUILD_SLICE 2 -\\d\+ LOAD_SUBSCR -\\d\+ STORE_FAST 0 -\\d\+ LOAD_FAST 1 -\\d\+ UNPACK_SEQUENCE 2 -\\d\+ STORE_FAST 0 -\\d\+ STORE_DEREF 14 -\\d\+ LOAD_FAST 0 -\\d\+ UNPACK_EX 1 -\\d\+ STORE_FAST 0 -\\d\+ STORE_FAST 0 -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_FAST 0 -\\d\+ ROT_TWO -\\d\+ STORE_FAST 0 -\\d\+ STORE_DEREF 14 -\\d\+ LOAD_FAST 1 -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_FAST 0 -\\d\+ ROT_THREE -\\d\+ ROT_TWO -\\d\+ STORE_FAST 0 -\\d\+ STORE_DEREF 14 -\\d\+ STORE_FAST 1 -\\d\+ DELETE_FAST 0 -\\d\+ LOAD_FAST 0 -\\d\+ STORE_GLOBAL gl -\\d\+ DELETE_GLOBAL gl -\\d\+ LOAD_FAST 14 -\\d\+ LOAD_FAST 15 -\\d\+ MAKE_CLOSURE \.\+ 2 -\\d\+ LOAD_FAST 2 -\\d\+ GET_ITER -\\d\+ CALL_FUNCTION n=1 nkw=0 -\\d\+ STORE_FAST 0 -\\d\+ LOAD_FAST 14 -\\d\+ LOAD_FAST 15 -\\d\+ MAKE_CLOSURE \.\+ 2 -\\d\+ LOAD_FAST 2 -\\d\+ CALL_FUNCTION n=1 nkw=0 -\\d\+ STORE_FAST 0 -\\d\+ LOAD_FAST 14 -\\d\+ LOAD_FAST 15 -\\d\+ MAKE_CLOSURE \.\+ 2 -\\d\+ LOAD_FAST 2 -\\d\+ CALL_FUNCTION n=1 nkw=0 -\\d\+ STORE_FAST 0 -\\d\+ LOAD_FAST 0 -\\d\+ CALL_FUNCTION n=0 nkw=0 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ CALL_FUNCTION n=1 nkw=0 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_CONST_STRING 'b' -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ CALL_FUNCTION n=0 nkw=1 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_DEREF 14 -\\d\+ LOAD_NULL -\\d\+ CALL_FUNCTION_VAR_KW n=0 nkw=0 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_METHOD b -\\d\+ CALL_METHOD n=0 nkw=0 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_METHOD b -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ CALL_METHOD n=1 nkw=0 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_METHOD b -\\d\+ LOAD_CONST_STRING 'c' -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ CALL_METHOD n=0 nkw=1 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_METHOD b -\\d\+ LOAD_FAST 1 -\\d\+ LOAD_NULL -\\d\+ CALL_METHOD_VAR_KW n=0 nkw=0 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ POP_JUMP_IF_FALSE \\d\+ -\\d\+ LOAD_DEREF 16 -\\d\+ POP_TOP -\\d\+ JUMP \\d\+ -\\d\+ LOAD_GLOBAL y -\\d\+ POP_TOP -\\d\+ JUMP \\d\+ -\\d\+ LOAD_DEREF 14 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ POP_JUMP_IF_TRUE \\d\+ -\\d\+ JUMP \\d\+ -\\d\+ LOAD_DEREF 14 -\\d\+ POP_TOP -\\d\+ LOAD_FAST 0 -\\d\+ POP_JUMP_IF_FALSE \\d\+ -\\d\+ LOAD_FAST 0 -\\d\+ JUMP_IF_TRUE_OR_POP \\d\+ -\\d\+ LOAD_FAST 0 -\\d\+ STORE_FAST 0 -\\d\+ LOAD_DEREF 14 -\\d\+ GET_ITER_STACK -\\d\+ FOR_ITER \\d\+ -\\d\+ STORE_FAST 0 -\\d\+ LOAD_FAST 1 -\\d\+ POP_TOP -\\d\+ JUMP \\d\+ -\\d\+ SETUP_FINALLY \\d\+ -\\d\+ SETUP_EXCEPT \\d\+ -\\d\+ JUMP \\d\+ -\\d\+ JUMP \\d\+ -\\d\+ LOAD_FAST 0 -\\d\+ POP_JUMP_IF_TRUE \\d\+ -\\d\+ POP_EXCEPT_JUMP \\d\+ -\\d\+ POP_TOP -\\d\+ LOAD_DEREF 14 -\\d\+ POP_TOP -\\d\+ POP_EXCEPT_JUMP \\d\+ -\\d\+ END_FINALLY -\\d\+ LOAD_CONST_NONE -\\d\+ LOAD_FAST 1 -\\d\+ POP_TOP -\\d\+ END_FINALLY -\\d\+ JUMP \\d\+ -\\d\+ SETUP_EXCEPT \\d\+ -\\d\+ UNWIND_JUMP \\d\+ 1 -\\d\+ POP_EXCEPT_JUMP \\d\+ -\\d\+ POP_TOP -\\d\+ POP_EXCEPT_JUMP \\d\+ -\\d\+ END_FINALLY -\\d\+ LOAD_FAST 0 -\\d\+ POP_JUMP_IF_TRUE \\d\+ -\\d\+ LOAD_FAST 0 -\\d\+ SETUP_WITH \\d\+ -\\d\+ POP_TOP -\\d\+ LOAD_DEREF 14 -\\d\+ POP_TOP -\\d\+ LOAD_CONST_NONE -\\d\+ WITH_CLEANUP -\\d\+ END_FINALLY -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ STORE_DEREF 16 -\\d\+ LOAD_FAST_N 16 -\\d\+ MAKE_CLOSURE \.\+ 1 -\\d\+ STORE_FAST 13 -\\d\+ LOAD_CONST_SMALL_INT 0 -\\d\+ LOAD_CONST_NONE -\\d\+ IMPORT_NAME 'a' -\\d\+ STORE_FAST 0 -\\d\+ LOAD_CONST_SMALL_INT 0 -\\d\+ LOAD_CONST_STRING 'b' -\\d\+ BUILD_TUPLE 1 -\\d\+ IMPORT_NAME 'a' -\\d\+ IMPORT_FROM 'b' -\\d\+ STORE_DEREF 14 -\\d\+ POP_TOP -\\d\+ RAISE_LAST -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ RAISE_OBJ -\\d\+ LOAD_CONST_NONE -\\d\+ RETURN_VALUE -\\d\+ LOAD_CONST_SMALL_INT 1 -\\d\+ RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+rg names: +18 LOAD_CONST_OBJ \.\+=(1, 2) +20 STORE_DEREF 14 +22 LOAD_CONST_SMALL_INT 1 +23 LOAD_CONST_SMALL_INT 2 +24 BUILD_LIST 2 +26 STORE_FAST 1 +27 LOAD_CONST_SMALL_INT 1 +28 LOAD_CONST_SMALL_INT 2 +29 BUILD_SET 2 +31 STORE_FAST 2 +32 BUILD_MAP 0 +34 STORE_DEREF 15 +36 BUILD_MAP 1 +38 LOAD_CONST_SMALL_INT 2 +39 LOAD_CONST_SMALL_INT 1 +40 STORE_MAP +41 STORE_FAST 3 +42 LOAD_CONST_STRING 'a' +44 STORE_FAST 4 +45 LOAD_CONST_OBJ \.\+=b'a' +47 STORE_FAST 5 +48 LOAD_CONST_SMALL_INT 1 +49 STORE_FAST 6 +50 LOAD_CONST_SMALL_INT 2 +51 STORE_FAST 7 +52 LOAD_FAST 0 +53 LOAD_DEREF 14 +55 BINARY_OP 27 __add__ +56 STORE_FAST 8 +57 LOAD_FAST 0 +58 UNARY_OP 1 __neg__ +59 STORE_FAST 9 +60 LOAD_FAST 0 +61 UNARY_OP 3 +62 STORE_FAST 10 +63 LOAD_FAST 0 +64 LOAD_DEREF 14 +66 DUP_TOP +67 ROT_THREE +68 BINARY_OP 2 __eq__ +69 JUMP_IF_FALSE_OR_POP 75 +71 LOAD_FAST 1 +72 BINARY_OP 2 __eq__ +73 JUMP 77 +75 ROT_TWO +76 POP_TOP +77 STORE_FAST 10 +78 LOAD_FAST 0 +79 LOAD_DEREF 14 +81 BINARY_OP 2 __eq__ +82 JUMP_IF_FALSE_OR_POP 88 +84 LOAD_DEREF 14 +86 LOAD_FAST 1 +87 BINARY_OP 2 __eq__ +88 UNARY_OP 3 +89 STORE_FAST 10 +90 LOAD_DEREF 14 +92 LOAD_ATTR c +94 STORE_FAST 11 +95 LOAD_FAST 11 +96 LOAD_DEREF 14 +98 STORE_ATTR c +100 LOAD_DEREF 14 +102 LOAD_CONST_SMALL_INT 0 +103 LOAD_SUBSCR +104 STORE_FAST 12 +105 LOAD_FAST 12 +106 LOAD_DEREF 14 +108 LOAD_CONST_SMALL_INT 0 +109 STORE_SUBSCR +110 LOAD_DEREF 14 +112 LOAD_CONST_SMALL_INT 0 +113 DUP_TOP_TWO +114 LOAD_SUBSCR +115 LOAD_FAST 12 +116 BINARY_OP 14 __iadd__ +117 ROT_THREE +118 STORE_SUBSCR +119 LOAD_DEREF 14 +121 LOAD_CONST_NONE +122 LOAD_CONST_NONE +123 BUILD_SLICE 2 +125 LOAD_SUBSCR +126 STORE_FAST 0 +127 LOAD_FAST 1 +128 UNPACK_SEQUENCE 2 +130 STORE_FAST 0 +131 STORE_DEREF 14 +133 LOAD_FAST 0 +134 UNPACK_EX 1 +136 STORE_FAST 0 +137 STORE_FAST 0 +138 LOAD_DEREF 14 +140 LOAD_FAST 0 +141 ROT_TWO +142 STORE_FAST 0 +143 STORE_DEREF 14 +145 LOAD_FAST 1 +146 LOAD_DEREF 14 +148 LOAD_FAST 0 +149 ROT_THREE +150 ROT_TWO +151 STORE_FAST 0 +152 STORE_DEREF 14 +154 STORE_FAST 1 +155 DELETE_FAST 0 +157 LOAD_FAST 0 +158 STORE_GLOBAL gl +160 DELETE_GLOBAL gl +162 LOAD_FAST 14 +163 LOAD_FAST 15 +164 MAKE_CLOSURE \.\+ 2 +167 LOAD_FAST 2 +168 GET_ITER +169 CALL_FUNCTION n=1 nkw=0 +171 STORE_FAST 0 +172 LOAD_FAST 14 +173 LOAD_FAST 15 +174 MAKE_CLOSURE \.\+ 2 +177 LOAD_FAST 2 +178 CALL_FUNCTION n=1 nkw=0 +180 STORE_FAST 0 +181 LOAD_FAST 14 +182 LOAD_FAST 15 +183 MAKE_CLOSURE \.\+ 2 +186 LOAD_FAST 2 +187 CALL_FUNCTION n=1 nkw=0 +189 STORE_FAST 0 +190 LOAD_FAST 0 +191 CALL_FUNCTION n=0 nkw=0 +193 POP_TOP +194 LOAD_FAST 0 +195 LOAD_CONST_SMALL_INT 1 +196 CALL_FUNCTION n=1 nkw=0 +198 POP_TOP +199 LOAD_FAST 0 +200 LOAD_CONST_STRING 'b' +202 LOAD_CONST_SMALL_INT 1 +203 CALL_FUNCTION n=0 nkw=1 +206 POP_TOP +207 LOAD_FAST 0 +208 LOAD_DEREF 14 +210 LOAD_CONST_SMALL_INT 1 +211 CALL_FUNCTION_VAR_KW n=1 nkw=0 +213 POP_TOP +214 LOAD_FAST 0 +215 LOAD_METHOD b +217 CALL_METHOD n=0 nkw=0 +219 POP_TOP +220 LOAD_FAST 0 +221 LOAD_METHOD b +223 LOAD_CONST_SMALL_INT 1 +224 CALL_METHOD n=1 nkw=0 +226 POP_TOP +227 LOAD_FAST 0 +228 LOAD_METHOD b +230 LOAD_CONST_STRING 'c' +232 LOAD_CONST_SMALL_INT 1 +233 CALL_METHOD n=0 nkw=1 +236 POP_TOP +237 LOAD_FAST 0 +238 LOAD_METHOD b +240 LOAD_FAST 1 +241 LOAD_CONST_SMALL_INT 1 +242 CALL_METHOD_VAR_KW n=1 nkw=0 +244 POP_TOP +245 LOAD_FAST 0 +246 POP_JUMP_IF_FALSE 253 +248 LOAD_DEREF 16 +250 POP_TOP +251 JUMP 256 +253 LOAD_GLOBAL y +255 POP_TOP +256 JUMP 261 +258 LOAD_DEREF 14 +260 POP_TOP +261 LOAD_FAST 0 +262 POP_JUMP_IF_TRUE 258 +264 JUMP 269 +266 LOAD_DEREF 14 +268 POP_TOP +269 LOAD_FAST 0 +270 POP_JUMP_IF_FALSE 266 +272 LOAD_FAST 0 +273 JUMP_IF_TRUE_OR_POP 276 +275 LOAD_FAST 0 +276 STORE_FAST 0 +277 LOAD_DEREF 14 +279 GET_ITER_STACK +280 FOR_ITER 287 +282 STORE_FAST 0 +283 LOAD_FAST 1 +284 POP_TOP +285 JUMP 280 +287 SETUP_FINALLY 308 +289 SETUP_EXCEPT 300 +291 JUMP 295 +293 JUMP 298 +295 LOAD_FAST 0 +296 POP_JUMP_IF_TRUE 293 +298 POP_EXCEPT_JUMP 307 +300 POP_TOP +301 LOAD_DEREF 14 +303 POP_TOP +304 POP_EXCEPT_JUMP 307 +306 END_FINALLY +307 LOAD_CONST_NONE +308 LOAD_FAST 1 +309 POP_TOP +310 END_FINALLY +311 JUMP 324 +313 SETUP_EXCEPT 320 +315 UNWIND_JUMP 327 1 +318 POP_EXCEPT_JUMP 324 +320 POP_TOP +321 POP_EXCEPT_JUMP 324 +323 END_FINALLY +324 LOAD_FAST 0 +325 POP_JUMP_IF_TRUE 313 +327 LOAD_FAST 0 +328 SETUP_WITH 335 +330 POP_TOP +331 LOAD_DEREF 14 +333 POP_TOP +334 LOAD_CONST_NONE +335 WITH_CLEANUP +336 END_FINALLY +337 LOAD_CONST_SMALL_INT 1 +338 STORE_DEREF 16 +340 LOAD_FAST_N 16 +342 MAKE_CLOSURE \.\+ 1 +345 STORE_FAST 13 +346 LOAD_CONST_SMALL_INT 0 +347 LOAD_CONST_NONE +348 IMPORT_NAME 'a' +350 STORE_FAST 0 +351 LOAD_CONST_SMALL_INT 0 +352 LOAD_CONST_STRING 'b' +354 BUILD_TUPLE 1 +356 IMPORT_NAME 'a' +358 IMPORT_FROM 'b' +360 STORE_DEREF 14 +362 POP_TOP +363 RAISE_LAST +364 LOAD_CONST_SMALL_INT 1 +365 RAISE_OBJ +366 LOAD_CONST_NONE +367 RETURN_VALUE +368 LOAD_CONST_SMALL_INT 1 +369 RETURN_VALUE +File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 59 bytes) +Raw bytecode (code_info_size=8, bytecode_size=51): + a8 10 0a 05 80 82 34 38 81 57 c0 57 c1 57 c2 57 + c3 57 c4 57 c5 57 c6 57 c7 57 c8 c9 82 57 ca 57 + cb 57 cc 57 cd 57 ce 57 cf 57 26 10 57 26 11 57 + 26 12 26 13 b9 24 13 f2 59 51 63 +arg names: (N_STATE 22) (N_EXC_STACK 0) bc=0 line=1 -######## - bc=\\d\+ line=133 + bc=0 line=131 + bc=20 line=132 + bc=44 line=133 00 LOAD_CONST_SMALL_INT 1 01 DUP_TOP 02 STORE_FAST 0 @@ -366,28 +462,29 @@ Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): 48 POP_TOP 49 LOAD_CONST_NONE 50 RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 20 bytes) +Raw bytecode (code_info_size=9, bytecode_size=11): + a1 01 0b 05 06 80 88 40 00 82 2a 01 53 b0 21 00 + 01 c1 51 63 arg names: a (N_STATE 5) (N_EXC_STACK 0) (INIT_CELL 0) -######## - bc=\\d\+ line=139 + bc=0 line=1 + bc=0 line=137 + bc=0 line=139 00 LOAD_CONST_SMALL_INT 2 01 BUILD_TUPLE 1 03 LOAD_NULL 04 LOAD_FAST 0 05 MAKE_CLOSURE_DEFARGS \.\+ 1 -\\d\+ STORE_FAST 1 -\\d\+ LOAD_CONST_NONE -\\d\+ RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +08 STORE_FAST 1 +09 LOAD_CONST_NONE +10 RETURN_VALUE +File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 21 bytes) +Raw bytecode (code_info_size=8, bytecode_size=13): + 88 40 0a 05 80 8f 23 23 51 67 59 81 67 59 81 5e + 51 68 59 51 63 arg names: (N_STATE 2) (N_EXC_STACK 0) @@ -408,115 +505,113 @@ arg names: 10 POP_TOP 11 LOAD_CONST_NONE 12 RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'Class' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +File cmdline/cmd_showbc.py, code block 'Class' (descriptor: \.\+, bytecode @\.\+ 1\[56\] bytes) +Raw bytecode (code_info_size=\[56\], bytecode_size=10): + 00 \.\+ 11 0f 16 10 10 02 16 11 51 63 arg names: (N_STATE 1) (N_EXC_STACK 0) bc=0 line=1 ######## - bc=12 line=150 + bc=8 line=150 00 LOAD_NAME __name__ -03 STORE_NAME __module__ -06 LOAD_CONST_STRING 'Class' -09 STORE_NAME __qualname__ -12 LOAD_CONST_NONE -13 RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +02 STORE_NAME __module__ +04 LOAD_CONST_STRING 'Class' +06 STORE_NAME __qualname__ +08 LOAD_CONST_NONE +09 RETURN_VALUE +File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 18 bytes) +Raw bytecode (code_info_size=6, bytecode_size=12): + 19 08 05 12 80 9c 12 13 12 14 b0 15 05 36 00 59 + 51 63 arg names: self (N_STATE 4) (N_EXC_STACK 0) bc=0 line=1 bc=0 line=157 00 LOAD_GLOBAL super -\\d\+ LOAD_GLOBAL __class__ -\\d\+ LOAD_FAST 0 -\\d\+ LOAD_SUPER_METHOD f -\\d\+ CALL_METHOD n=0 nkw=0 -\\d\+ POP_TOP -\\d\+ LOAD_CONST_NONE -\\d\+ RETURN_VALUE -File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +02 LOAD_GLOBAL __class__ +04 LOAD_FAST 0 +05 LOAD_SUPER_METHOD f +07 CALL_METHOD n=0 nkw=0 +09 POP_TOP +10 LOAD_CONST_NONE +11 RETURN_VALUE +File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ 28 bytes) +Raw bytecode (code_info_size=9, bytecode_size=19): + c3 40 0c 09 03 03 03 80 3b 53 b2 53 53 4b 0b c3 + 25 01 44 39 25 00 67 59 42 33 51 63 arg names: * * * (N_STATE 9) (N_EXC_STACK 0) bc=0 line=1 bc=0 line=60 -######## 00 LOAD_NULL 01 LOAD_FAST 2 02 LOAD_NULL 03 LOAD_NULL -04 FOR_ITER 20 -07 STORE_FAST 3 -08 LOAD_DEREF 1 -10 POP_JUMP_IF_FALSE 4 -13 LOAD_DEREF 0 -15 YIELD_VALUE -16 POP_TOP -17 JUMP 4 -20 LOAD_CONST_NONE -21 RETURN_VALUE -File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +04 FOR_ITER 17 +06 STORE_FAST 3 +07 LOAD_DEREF 1 +09 POP_JUMP_IF_FALSE 4 +11 LOAD_DEREF 0 +13 YIELD_VALUE +14 POP_TOP +15 JUMP 4 +17 LOAD_CONST_NONE +18 RETURN_VALUE +File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ 26 bytes) +Raw bytecode (code_info_size=8, bytecode_size=18): + 4b 0c 0a 03 03 03 80 3c 2b 00 b2 5f 4b 0b c3 25 + 01 44 39 25 00 2f 14 42 33 63 arg names: * * * (N_STATE 10) (N_EXC_STACK 0) bc=0 line=1 bc=0 line=61 -######## 00 BUILD_LIST 0 02 LOAD_FAST 2 03 GET_ITER_STACK -04 FOR_ITER 20 -07 STORE_FAST 3 -08 LOAD_DEREF 1 -10 POP_JUMP_IF_FALSE 4 -13 LOAD_DEREF 0 -15 STORE_COMP 20 -17 JUMP 4 -20 RETURN_VALUE -File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +04 FOR_ITER 17 +06 STORE_FAST 3 +07 LOAD_DEREF 1 +09 POP_JUMP_IF_FALSE 4 +11 LOAD_DEREF 0 +13 STORE_COMP 20 +15 JUMP 4 +17 RETURN_VALUE +File cmdline/cmd_showbc.py, code block '' (descriptor: \.\+, bytecode @\.\+ 28 bytes) +Raw bytecode (code_info_size=8, bytecode_size=20): + 53 0c 0b 03 03 03 80 3d 2c 00 b2 5f 4b 0d c3 25 + 01 44 39 25 00 25 00 2f 19 42 31 63 arg names: * * * (N_STATE 11) (N_EXC_STACK 0) bc=0 line=1 -######## + bc=0 line=62 00 BUILD_MAP 0 02 LOAD_FAST 2 03 GET_ITER_STACK -04 FOR_ITER 22 -07 STORE_FAST 3 -08 LOAD_DEREF 1 -10 POP_JUMP_IF_FALSE 4 +04 FOR_ITER 19 +06 STORE_FAST 3 +07 LOAD_DEREF 1 +09 POP_JUMP_IF_FALSE 4 +11 LOAD_DEREF 0 13 LOAD_DEREF 0 -15 LOAD_DEREF 0 -17 STORE_COMP 25 -19 JUMP 4 -22 RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'closure' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +15 STORE_COMP 25 +17 JUMP 4 +19 RETURN_VALUE +File cmdline/cmd_showbc.py, code block 'closure' (descriptor: \.\+, bytecode @\.\+ 20 bytes) +Raw bytecode (code_info_size=8, bytecode_size=12): + 19 0c 0c 03 80 6f 25 23 25 00 81 f2 c1 81 27 00 + 29 00 51 63 arg names: * (N_STATE 4) (N_EXC_STACK 0) bc=0 line=1 -######## - bc=\\d\+ line=114 + bc=0 line=112 + bc=5 line=113 + bc=8 line=114 00 LOAD_DEREF 0 02 LOAD_CONST_SMALL_INT 1 03 BINARY_OP 27 __add__ @@ -526,16 +621,14 @@ arg names: * 08 DELETE_DEREF 0 10 LOAD_CONST_NONE 11 RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): -######## -\.\+63 +File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 13 bytes) +Raw bytecode (code_info_size=8, bytecode_size=5): + 9a 01 0a 05 03 08 80 8b b1 25 00 f2 63 arg names: * b (N_STATE 4) (N_EXC_STACK 0) bc=0 line=1 -######## - bc=\\d\+ line=140 + bc=0 line=140 00 LOAD_FAST 1 01 LOAD_DEREF 0 03 BINARY_OP 27 __add__ diff --git a/tests/cmdline/cmd_verbose.py.exp b/tests/cmdline/cmd_verbose.py.exp index 0edd050c22221..ae833dbec8d3e 100644 --- a/tests/cmdline/cmd_verbose.py.exp +++ b/tests/cmdline/cmd_verbose.py.exp @@ -1,19 +1,17 @@ -File cmdline/cmd_verbose.py, code block '' (descriptor: \.\+, bytecode \.\+ bytes) -Raw bytecode (code_info_size=\\d\+, bytecode_size=\\d\+): - 08 \.\+ -######## -\.\+63 +File cmdline/cmd_verbose.py, code block '' (descriptor: \.\+, bytecode @\.\+ 12 bytes) +Raw bytecode (code_info_size=4, bytecode_size=8): + 08 04 01 40 11 02 81 34 01 59 51 63 arg names: (N_STATE 2) (N_EXC_STACK 0) bc=0 line=1 bc=0 line=3 00 LOAD_NAME print -03 LOAD_CONST_SMALL_INT 1 -04 CALL_FUNCTION n=1 nkw=0 -06 POP_TOP -07 LOAD_CONST_NONE -08 RETURN_VALUE +02 LOAD_CONST_SMALL_INT 1 +03 CALL_FUNCTION n=1 nkw=0 +05 POP_TOP +06 LOAD_CONST_NONE +07 RETURN_VALUE 1 mem: total=\\d\+, current=\\d\+, peak=\\d\+ stack: \\d\+ out of \\d\+ diff --git a/tests/cmdline/repl_autoindent.py b/tests/cmdline/repl_autoindent.py new file mode 100644 index 0000000000000..152c81895f196 --- /dev/null +++ b/tests/cmdline/repl_autoindent.py @@ -0,0 +1,16 @@ +# tests for autoindent +if 1: +print(1) + + + +if 0: + print(2) +else: + print(3) + +if 0: + print(4) +else: + print(5) + diff --git a/tests/cmdline/repl_autoindent.py.exp b/tests/cmdline/repl_autoindent.py.exp new file mode 100644 index 0000000000000..9127a7d31d903 --- /dev/null +++ b/tests/cmdline/repl_autoindent.py.exp @@ -0,0 +1,22 @@ +MicroPython \.\+ version +Use \.\+ +>>> # tests for autoindent +>>> if 1: +... print(1) +... +... +... +1 +>>> if 0: +...  print(2) +... else: +... print(3) +... +3 +>>> if 0: +... print(4) +... else: +... print(5) +... +5 +>>> diff --git a/tests/cmdline/repl_sys_ps1_ps2.py b/tests/cmdline/repl_sys_ps1_ps2.py new file mode 100644 index 0000000000000..4f96057c49b6d --- /dev/null +++ b/tests/cmdline/repl_sys_ps1_ps2.py @@ -0,0 +1,6 @@ +# test changing ps1/ps2 +import usys +usys.ps1 = "PS1" +usys.ps2 = "PS2" +(1 + +2) diff --git a/tests/cmdline/repl_sys_ps1_ps2.py.exp b/tests/cmdline/repl_sys_ps1_ps2.py.exp new file mode 100644 index 0000000000000..e4a802d34d75e --- /dev/null +++ b/tests/cmdline/repl_sys_ps1_ps2.py.exp @@ -0,0 +1,10 @@ +MicroPython \.\+ version +Use \.\+ +>>> # test changing ps1/ps2 +>>> import usys +>>> usys.ps1 = "PS1" +PS1usys.ps2 = "PS2" +PS1(1 + +PS22) +3 +PS1 diff --git a/tests/cpydiff/syntax_arg_unpacking.py b/tests/cpydiff/syntax_arg_unpacking.py new file mode 100644 index 0000000000000..e54832ddb9165 --- /dev/null +++ b/tests/cpydiff/syntax_arg_unpacking.py @@ -0,0 +1,23 @@ +""" +categories: Syntax +description: Argument unpacking does not work if the argument being unpacked is the nth or greater argument where n is the number of bits in an MP_SMALL_INT. +cause: The implementation uses an MP_SMALL_INT to flag args that need to be unpacked. +workaround: Use fewer arguments. +""" + + +def example(*args): + print(len(args)) + + +MORE = ["a", "b", "c"] + +# fmt: off +example( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + *MORE, +) +# fmt: on diff --git a/tests/endorse.py b/tests/endorse.py new file mode 100755 index 0000000000000..c87424329f6b1 --- /dev/null +++ b/tests/endorse.py @@ -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) diff --git a/tests/extmod/uasyncio_await_return.py b/tests/extmod/uasyncio_await_return.py index d375c9ea97ab3..4a45d9b9c0649 100644 --- a/tests/extmod/uasyncio_await_return.py +++ b/tests/extmod/uasyncio_await_return.py @@ -14,6 +14,13 @@ async def foo(): return 42 +try: + foo().__await__ +except AttributeError: + print("SKIP") + raise SystemExit + + async def main(): # Call function directly via an await print(await foo()) diff --git a/tests/extmod/uasyncio_basic.py b/tests/extmod/uasyncio_basic.py index c88908d99b320..baf9d193fe0b6 100644 --- a/tests/extmod/uasyncio_basic.py +++ b/tests/extmod/uasyncio_basic.py @@ -8,6 +8,16 @@ raise SystemExit +async def foo(): + return 42 + + +try: + foo().__await__ +except AttributeError: + print("SKIP") + raise SystemExit + try: import utime @@ -32,18 +42,18 @@ async def main(): print("after sleep") t0 = ticks() - await delay_print(0.02, "short") + await delay_print(0.2, "short") t1 = ticks() - await delay_print(0.04, "long") + await delay_print(0.4, "long") t2 = ticks() await delay_print(-1, "negative") t3 = ticks() print( "took {} {} {}".format( - round(ticks_diff(t1, t0), -1), - round(ticks_diff(t2, t1), -1), - round(ticks_diff(t3, t2), -1), + round(ticks_diff(t1, t0), -2), + round(ticks_diff(t2, t1), -2), + round(ticks_diff(t3, t2), -2), ) ) diff --git a/tests/extmod/uasyncio_basic.py.exp b/tests/extmod/uasyncio_basic.py.exp index 6673978769fbf..478e22abc8ff6 100644 --- a/tests/extmod/uasyncio_basic.py.exp +++ b/tests/extmod/uasyncio_basic.py.exp @@ -3,4 +3,4 @@ after sleep short long negative -took 20 40 0 +took 200 400 0 diff --git a/tests/extmod/uasyncio_event_fair.py b/tests/extmod/uasyncio_event_fair.py index 37eca5faef10b..1eee0bd7e8576 100644 --- a/tests/extmod/uasyncio_event_fair.py +++ b/tests/extmod/uasyncio_event_fair.py @@ -11,6 +11,17 @@ raise SystemExit +async def foo(): + return 42 + + +try: + foo().__await__ +except AttributeError: + print("SKIP") + raise SystemExit + + async def task1(id): for i in range(4): print("sleep", id) diff --git a/tests/extmod/uasyncio_gather.py b/tests/extmod/uasyncio_gather.py index 6053873dbc1ae..e34176a31d0a9 100644 --- a/tests/extmod/uasyncio_gather.py +++ b/tests/extmod/uasyncio_gather.py @@ -10,6 +10,17 @@ raise SystemExit +async def foo(): + return 42 + + +try: + foo().__await__ +except AttributeError: + print("SKIP") + raise SystemExit + + async def factorial(name, number): f = 1 for i in range(2, number + 1): @@ -20,16 +31,30 @@ async def factorial(name, number): return f -async def task(id): +async def task(id, t=0.1): print("start", id) - await asyncio.sleep(0.02) + await asyncio.sleep(t) print("end", id) return id -async def gather_task(): +async def task_loop(id): + print("task_loop start", id) + while True: + await asyncio.sleep(0.1) + print("task_loop loop", id) + + +async def task_raise(id, t=0.1): + print("task_raise start", id) + await asyncio.sleep(t) + print("task_raise raise", id) + raise ValueError(id) + + +async def gather_task(t0, t1): print("gather_task") - await asyncio.gather(task(1), task(2)) + await asyncio.gather(t0, t1) print("gather_task2") @@ -37,19 +62,59 @@ async def main(): # Simple gather with return values print(await asyncio.gather(factorial("A", 2), factorial("B", 3), factorial("C", 4))) + print("====") + # Test return_exceptions, where one task is cancelled and the other finishes normally tasks = [asyncio.create_task(task(1)), asyncio.create_task(task(2))] tasks[0].cancel() print(await asyncio.gather(*tasks, return_exceptions=True)) - # Cancel a multi gather - # TODO doesn't work, Task should not forward cancellation from gather to sub-task - # but rather CancelledError should cancel the gather directly, which will then cancel - # all sub-tasks explicitly - # t = asyncio.create_task(gather_task()) - # await asyncio.sleep(0.01) - # t.cancel() - # await asyncio.sleep(0.01) + print("====") + + # Test return_exceptions, where one task raises an exception and the other finishes normally. + tasks = [asyncio.create_task(task(1)), asyncio.create_task(task_raise(2))] + print(await asyncio.gather(*tasks, return_exceptions=True)) + + print("====") + + # Test case where one task raises an exception and other task keeps running. + tasks = [asyncio.create_task(task_loop(1)), asyncio.create_task(task_raise(2))] + try: + await asyncio.gather(*tasks) + except ValueError as er: + print(repr(er)) + print(tasks[0].done(), tasks[1].done()) + for t in tasks: + t.cancel() + await asyncio.sleep(0.2) + + print("====") + + # Test case where both tasks raise an exception. + # Use t=0 so they raise one after the other, between the gather starting and finishing. + tasks = [asyncio.create_task(task_raise(1, t=0)), asyncio.create_task(task_raise(2, t=0))] + try: + await asyncio.gather(*tasks) + except ValueError as er: + print(repr(er)) + print(tasks[0].done(), tasks[1].done()) + + print("====") + + # Cancel a multi gather. + t = asyncio.create_task(gather_task(task(1), task(2))) + await asyncio.sleep(0.05) + t.cancel() + await asyncio.sleep(0.2) + + # Test edge cases where the gather is cancelled just as tasks are created and ending. + for i in range(1, 4): + print("====") + t = asyncio.create_task(gather_task(task(1, t=0), task(2, t=0))) + for _ in range(i): + await asyncio.sleep(0) + t.cancel() + await asyncio.sleep(0.2) asyncio.run(main()) diff --git a/tests/extmod/uasyncio_gather.py.exp b/tests/extmod/uasyncio_gather.py.exp index 95310bbe1c105..a5ea47ab500d8 100644 --- a/tests/extmod/uasyncio_gather.py.exp +++ b/tests/extmod/uasyncio_gather.py.exp @@ -8,6 +8,47 @@ Task B: factorial(3) = 6 Task C: Compute factorial(4)... Task C: factorial(4) = 24 [2, 6, 24] +==== start 2 end 2 [CancelledError(), 2] +==== +start 1 +task_raise start 2 +end 1 +task_raise raise 2 +[1, ValueError(2,)] +==== +task_loop start 1 +task_raise start 2 +task_loop loop 1 +task_raise raise 2 +ValueError(2,) +False True +==== +task_raise start 1 +task_raise start 2 +task_raise raise 1 +task_raise raise 2 +ValueError(1,) +True True +==== +gather_task +start 1 +start 2 +==== +gather_task +start 1 +start 2 +==== +gather_task +start 1 +start 2 +end 1 +end 2 +==== +gather_task +start 1 +start 2 +end 1 +end 2 diff --git a/tests/extmod/uasyncio_gather_notimpl.py b/tests/extmod/uasyncio_gather_notimpl.py new file mode 100644 index 0000000000000..63ba645d24ad0 --- /dev/null +++ b/tests/extmod/uasyncio_gather_notimpl.py @@ -0,0 +1,64 @@ +# Test uasyncio.gather() function, features that are not implemented. + +try: + import uasyncio as asyncio +except ImportError: + try: + import asyncio + except ImportError: + print("SKIP") + raise SystemExit + + +async def foo(): + return 42 + + +try: + foo().__await__ +except AttributeError: + print("SKIP") + raise SystemExit + + +def custom_handler(loop, context): + print(repr(context["exception"])) + + +async def task(id): + print("task start", id) + await asyncio.sleep(0.01) + print("task end", id) + return id + + +async def gather_task(t0, t1): + print("gather_task start") + await asyncio.gather(t0, t1) + print("gather_task end") + + +async def main(): + loop = asyncio.get_event_loop() + loop.set_exception_handler(custom_handler) + + # Test case where can't wait on a task being gathered. + tasks = [asyncio.create_task(task(1)), asyncio.create_task(task(2))] + gt = asyncio.create_task(gather_task(tasks[0], tasks[1])) + await asyncio.sleep(0) # let the gather start + try: + await tasks[0] # can't await because this task is part of the gather + except RuntimeError as er: + print(repr(er)) + await gt + + print("====") + + # Test case where can't gather on a task being waited. + tasks = [asyncio.create_task(task(1)), asyncio.create_task(task(2))] + asyncio.create_task(gather_task(tasks[0], tasks[1])) + await tasks[0] # wait on this task before the gather starts + await tasks[1] + + +asyncio.run(main()) diff --git a/tests/extmod/uasyncio_gather_notimpl.py.exp b/tests/extmod/uasyncio_gather_notimpl.py.exp new file mode 100644 index 0000000000000..f21614ffbe671 --- /dev/null +++ b/tests/extmod/uasyncio_gather_notimpl.py.exp @@ -0,0 +1,14 @@ +task start 1 +task start 2 +gather_task start +RuntimeError("can't wait",) +task end 1 +task end 2 +gather_task end +==== +task start 1 +task start 2 +gather_task start +RuntimeError("can't gather",) +task end 1 +task end 2 diff --git a/tests/extmod/uasyncio_heaplock.py b/tests/extmod/uasyncio_heaplock.py index 3a92d36c9f57b..34a51cd370e52 100644 --- a/tests/extmod/uasyncio_heaplock.py +++ b/tests/extmod/uasyncio_heaplock.py @@ -29,15 +29,15 @@ async def task(id, n, t): async def main(): - t1 = asyncio.create_task(task(1, 4, 20)) - t2 = asyncio.create_task(task(2, 2, 50)) + t1 = asyncio.create_task(task(1, 4, 100)) + t2 = asyncio.create_task(task(2, 2, 250)) micropython.heap_lock() print("start") - await asyncio.sleep_ms(1) + await asyncio.sleep_ms(5) print("sleep") - await asyncio.sleep_ms(70) + await asyncio.sleep_ms(350) print("finish") micropython.heap_unlock() diff --git a/tests/extmod/uasyncio_lock_cancel.py b/tests/extmod/uasyncio_lock_cancel.py index 85b8df8483065..27428da80b86d 100644 --- a/tests/extmod/uasyncio_lock_cancel.py +++ b/tests/extmod/uasyncio_lock_cancel.py @@ -10,6 +10,17 @@ raise SystemExit +async def foo(): + return 42 + + +try: + foo().__await__ +except AttributeError: + print("SKIP") + raise SystemExit + + async def task(i, lock, lock_flag): print("task", i, "start") try: diff --git a/tests/extmod/uasyncio_threadsafeflag.py b/tests/extmod/uasyncio_threadsafeflag.py new file mode 100644 index 0000000000000..4e002a3d2a0b1 --- /dev/null +++ b/tests/extmod/uasyncio_threadsafeflag.py @@ -0,0 +1,79 @@ +# Test Event class + +try: + import uasyncio as asyncio +except ImportError: + print("SKIP") + raise SystemExit + + +import micropython + +try: + micropython.schedule +except AttributeError: + print("SKIP") + raise SystemExit + + +try: + # Unix port can't select/poll on user-defined types. + import uselect as select + + poller = select.poll() + poller.register(asyncio.ThreadSafeFlag()) +except TypeError: + print("SKIP") + raise SystemExit + + +async def task(id, flag): + print("task", id) + await flag.wait() + print("task", id, "done") + + +def set_from_schedule(flag): + print("schedule") + flag.set() + print("schedule done") + + +async def main(): + flag = asyncio.ThreadSafeFlag() + + # Set the flag from within the loop. + t = asyncio.create_task(task(1, flag)) + print("yield") + await asyncio.sleep(0) + print("set event") + flag.set() + print("yield") + await asyncio.sleep(0) + print("wait task") + await t + + # Set the flag from scheduler context. + print("----") + t = asyncio.create_task(task(2, flag)) + print("yield") + await asyncio.sleep(0) + print("set event") + micropython.schedule(set_from_schedule, flag) + print("yield") + await asyncio.sleep(0) + print("wait task") + await t + + # Flag already set. + print("----") + print("set event") + flag.set() + t = asyncio.create_task(task(3, flag)) + print("yield") + await asyncio.sleep(0) + print("wait task") + await t + + +asyncio.run(main()) diff --git a/tests/extmod/uasyncio_threadsafeflag.py.exp b/tests/extmod/uasyncio_threadsafeflag.py.exp new file mode 100644 index 0000000000000..aef4e479ba447 --- /dev/null +++ b/tests/extmod/uasyncio_threadsafeflag.py.exp @@ -0,0 +1,21 @@ +yield +task 1 +set event +yield +wait task +task 1 done +---- +yield +task 2 +set event +yield +schedule +schedule done +wait task +task 2 done +---- +set event +yield +task 3 +task 3 done +wait task diff --git a/tests/extmod/uasyncio_wait_for.py b/tests/extmod/uasyncio_wait_for.py index 9612d16204043..c636c7dd747ad 100644 --- a/tests/extmod/uasyncio_wait_for.py +++ b/tests/extmod/uasyncio_wait_for.py @@ -111,6 +111,21 @@ async def main(): await asyncio.sleep(0.01) print(sep) + # When wait_for gets cancelled and the task it's waiting on finishes around the + # same time as the cancellation of the wait_for + for num_sleep in range(1, 5): + t = asyncio.create_task(task_wait_for_cancel(4 + num_sleep, 0, 2)) + for _ in range(num_sleep): + await asyncio.sleep(0) + assert not t.done() + print("cancel wait_for") + t.cancel() + try: + await t + except asyncio.CancelledError as er: + print(repr(er)) + print(sep) + print("finish") diff --git a/tests/extmod/uasyncio_wait_for.py.exp b/tests/extmod/uasyncio_wait_for.py.exp index a4201d31ffdb8..1bbe3d0658f84 100644 --- a/tests/extmod/uasyncio_wait_for.py.exp +++ b/tests/extmod/uasyncio_wait_for.py.exp @@ -32,4 +32,31 @@ task_wait_for_cancel_ignore cancelled ignore cancel task_catch done ---------- +task_wait_for_cancel start +cancel wait_for +task start 5 +task_wait_for_cancel cancelled +CancelledError() +---------- +task_wait_for_cancel start +task start 6 +cancel wait_for +task end 6 +task_wait_for_cancel cancelled +CancelledError() +---------- +task_wait_for_cancel start +task start 7 +task end 7 +cancel wait_for +task_wait_for_cancel cancelled +CancelledError() +---------- +task_wait_for_cancel start +task start 8 +task end 8 +cancel wait_for +task_wait_for_cancel cancelled +CancelledError() +---------- finish diff --git a/tests/extmod/uasyncio_wait_for_fwd.py b/tests/extmod/uasyncio_wait_for_fwd.py index 33738085ce4a5..e608f63f6bb36 100644 --- a/tests/extmod/uasyncio_wait_for_fwd.py +++ b/tests/extmod/uasyncio_wait_for_fwd.py @@ -10,6 +10,17 @@ raise SystemExit +async def foo(): + return 42 + + +try: + foo().__await__ +except AttributeError: + print("SKIP") + raise SystemExit + + async def awaiting(t, return_if_fail): try: print("awaiting started") diff --git a/tests/extmod/uasyncio_wait_task.py b/tests/extmod/uasyncio_wait_task.py index 3c79320c9f5c4..e19e29903ccc3 100644 --- a/tests/extmod/uasyncio_wait_task.py +++ b/tests/extmod/uasyncio_wait_task.py @@ -54,8 +54,8 @@ async def main(): print("----") # Create 2 tasks - ts1 = asyncio.create_task(delay_print(0.04, "hello")) - ts2 = asyncio.create_task(delay_print(0.08, "world")) + ts1 = asyncio.create_task(delay_print(0.2, "hello")) + ts2 = asyncio.create_task(delay_print(0.4, "world")) # Time how long the tasks take to finish, they should execute in parallel print("start") @@ -64,7 +64,7 @@ async def main(): t1 = ticks() await ts2 t2 = ticks() - print("took {} {}".format(round(ticks_diff(t1, t0), -1), round(ticks_diff(t2, t1), -1))) + print("took {} {}".format(round(ticks_diff(t1, t0), -2), round(ticks_diff(t2, t1), -2))) # Wait on a task that raises an exception t = asyncio.create_task(task_raise()) diff --git a/tests/extmod/uasyncio_wait_task.py.exp b/tests/extmod/uasyncio_wait_task.py.exp index ee4e70fb4eb1e..04be37f48406d 100644 --- a/tests/extmod/uasyncio_wait_task.py.exp +++ b/tests/extmod/uasyncio_wait_task.py.exp @@ -5,6 +5,6 @@ task 2 start hello world -took 40 40 +took 200 200 task_raise ValueError diff --git a/tests/extmod/ubinascii_b2a_base64.py b/tests/extmod/ubinascii_b2a_base64.py index 8c63b545a3bac..34f2f570559a9 100644 --- a/tests/extmod/ubinascii_b2a_base64.py +++ b/tests/extmod/ubinascii_b2a_base64.py @@ -24,3 +24,6 @@ print(binascii.b2a_base64("")) except TypeError: print("TypeError") + +print(binascii.b2a_base64(b"foobar", newline=True)) +print(binascii.b2a_base64(b"foobar", newline=False)) diff --git a/tests/extmod/uctypes_32bit_intbig.py b/tests/extmod/uctypes_32bit_intbig.py index eed36e87742af..27d33817cf618 100644 --- a/tests/extmod/uctypes_32bit_intbig.py +++ b/tests/extmod/uctypes_32bit_intbig.py @@ -6,7 +6,7 @@ print("SKIP") raise SystemExit -buf = b"12345678abcd" +buf = bytearray(b"12345678abcd") struct = uctypes.struct( uctypes.addressof(buf), {"f32": uctypes.UINT32 | 0, "f64": uctypes.UINT64 | 4}, @@ -30,7 +30,7 @@ print("=") -buf = b"12345678abcd" +buf = bytearray(b"12345678abcd") struct = uctypes.struct( uctypes.addressof(buf), {"f32": uctypes.UINT32 | 0, "f64": uctypes.UINT64 | 4}, diff --git a/tests/extmod/uctypes_32bit_intbig.py.exp b/tests/extmod/uctypes_32bit_intbig.py.exp index d1fc1fe350453..1b16ddbc3211b 100644 --- a/tests/extmod/uctypes_32bit_intbig.py.exp +++ b/tests/extmod/uctypes_32bit_intbig.py.exp @@ -1,11 +1,11 @@ -b'\xff\xff\xff\x7f5678abcd' -b'\x00\x00\x00\x805678abcd' -b'\x03\x02\x01\xff5678abcd' -b'\x03\x02\x01\xff\x00\x00\x00\x80\x00\x00\x00\x00' -b'\x03\x02\x01\xff\x00\x00\x00\x00\x01\x00\x00\x00' +bytearray(b'\xff\xff\xff\x7f5678abcd') +bytearray(b'\x00\x00\x00\x805678abcd') +bytearray(b'\x03\x02\x01\xff5678abcd') +bytearray(b'\x03\x02\x01\xff\x00\x00\x00\x80\x00\x00\x00\x00') +bytearray(b'\x03\x02\x01\xff\x00\x00\x00\x00\x01\x00\x00\x00') = -b'\x7f\xff\xff\xff5678abcd' -b'\x80\x00\x00\x005678abcd' -b'\xff\x01\x02\x035678abcd' -b'\xff\x01\x02\x03\x00\x00\x00\x00\x80\x00\x00\x00' -b'\xff\x01\x02\x03\x00\x00\x00\x01\x00\x00\x00\x00' +bytearray(b'\x7f\xff\xff\xff5678abcd') +bytearray(b'\x80\x00\x00\x005678abcd') +bytearray(b'\xff\x01\x02\x035678abcd') +bytearray(b'\xff\x01\x02\x03\x00\x00\x00\x00\x80\x00\x00\x00') +bytearray(b'\xff\x01\x02\x03\x00\x00\x00\x01\x00\x00\x00\x00') diff --git a/tests/extmod/ure_split.py b/tests/extmod/ure_split.py index a8b9c1686c658..7e6ef3990f4cd 100644 --- a/tests/extmod/ure_split.py +++ b/tests/extmod/ure_split.py @@ -31,3 +31,13 @@ r = re.compile(b"x") s = r.split(b"fooxbar") print(s) + +# using ^ +r = re.compile("^ab") +s = r.split("abababcabab") +print(s) + +# using ^ with | +r = re.compile("^ab|cab") +s = r.split("abababcabab") +print(s) diff --git a/tests/extmod/ure_sub.py b/tests/extmod/ure_sub.py index ae6ad28d621f4..806c38957627e 100644 --- a/tests/extmod/ure_sub.py +++ b/tests/extmod/ure_sub.py @@ -75,3 +75,7 @@ def A(): # Include \ in the sub replacement print(re.sub("b", "\\\\b", "abc")) + +# Using ^, make sure it doesn't repeatedly match +print(re.sub("^ab", "*", "abababcabab")) +print(re.sub("^ab|cab", "*", "abababcabab")) diff --git a/tests/extmod/vfs_fat_case.py b/tests/extmod/vfs_fat_case.py index 40d67da9b8241..cb02264dcb081 100644 --- a/tests/extmod/vfs_fat_case.py +++ b/tests/extmod/vfs_fat_case.py @@ -1,15 +1,9 @@ -try: - import uerrno - import uos -except ImportError: - print("missing u") - print("SKIP") - raise SystemExit +import errno as uerrno +import os as uos try: uos.VfsFat except AttributeError: - print("missing VfsFat") print("SKIP") raise SystemExit diff --git a/tests/extmod/vfs_fat_finaliser.py b/tests/extmod/vfs_fat_finaliser.py index c2f59669639fb..91cce2c95bda3 100644 --- a/tests/extmod/vfs_fat_finaliser.py +++ b/tests/extmod/vfs_fat_finaliser.py @@ -56,6 +56,12 @@ def ioctl(self, op, arg): # Here we test that the finaliser is actually called during a garbage collection. import gc +# Preallocate global variables, and list of filenames for the test (which may +# in turn allocate new qstrs and/or a new qstr pool). +f = None +n = None +names = ["x%d" % i for i in range(4)] + # Do a large number of single-block allocations to move the GC head forwards, # ensuring that the files are allocated from never-before-used blocks and # therefore couldn't possibly have any references to them left behind on @@ -63,14 +69,13 @@ def ioctl(self, op, arg): for i in range(1024): [] -N = 4 -for i in range(N): - n = "x%d" % i +# Run the test: create files without closing them, run GC, then read back files. +for n in names: f = vfs.open(n, "w") f.write(n) f = None # release f without closing - [0, 1, 2, 3, 4, 5] # use up Python stack so f is really gone + sorted([0, 1, 2, 3, 4, 5], key=lambda x: x) # use up Python and C stack so f is really gone gc.collect() # should finalise all N files by closing them -for i in range(N): - with vfs.open("x%d" % i, "r") as f: +for n in names: + with vfs.open(n, "r") as f: print(f.read()) diff --git a/tests/extmod/vfs_lfs_mount.py.exp b/tests/extmod/vfs_lfs_mount.py.exp index 68561b4807350..defaad0580761 100644 --- a/tests/extmod/vfs_lfs_mount.py.exp +++ b/tests/extmod/vfs_lfs_mount.py.exp @@ -13,4 +13,4 @@ package hello from lfs lfsmod2.py: print("hello from lfs") -OSError(36,) +OSError(30,) diff --git a/tests/extmod/vfs_posix.py b/tests/extmod/vfs_posix.py index f8c4aae40633f..2a14fc20767be 100644 --- a/tests/extmod/vfs_posix.py +++ b/tests/extmod/vfs_posix.py @@ -59,9 +59,10 @@ vfs = uos.VfsPosix(temp_dir) print(list(i[0] for i in vfs.ilistdir("."))) -# stat, statvfs +# stat, statvfs (statvfs may not exist) print(type(vfs.stat("."))) -print(type(vfs.statvfs("."))) +if hasattr(vfs, "statvfs"): + assert type(vfs.statvfs(".")) is tuple # check types of ilistdir with str/bytes arguments print(type(list(vfs.ilistdir("."))[0][0])) diff --git a/tests/extmod/vfs_posix.py.exp b/tests/extmod/vfs_posix.py.exp index e7d68f38ec7ca..eb9ab43106e1d 100644 --- a/tests/extmod/vfs_posix.py.exp +++ b/tests/extmod/vfs_posix.py.exp @@ -7,7 +7,6 @@ hello ['test2'] ['test2'] - [] diff --git a/tests/extmod/websocket_basic.py.exp b/tests/extmod/websocket_basic.py.exp deleted file mode 100644 index 2d7657b535407..0000000000000 --- a/tests/extmod/websocket_basic.py.exp +++ /dev/null @@ -1,14 +0,0 @@ -b'ping' -b'ping' -b'\x81\x04pong' -b'pingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingpingping' -b'\x81~\x00\x80pongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpongpong' -b'\x00\x00\x00\x00' -b'' -b'\x81\x02\x88\x00' -b'ping' -b'pong' -0 -1 -2 -ioctl: EINVAL: True diff --git a/tests/float/math_constants.py b/tests/float/math_constants.py new file mode 100644 index 0000000000000..2e4c321052625 --- /dev/null +++ b/tests/float/math_constants.py @@ -0,0 +1,11 @@ +# Tests various constants of the math module. +try: + import math + from math import exp, cos +except ImportError: + print("SKIP") + raise SystemExit + +print(math.e == exp(1.0)) + +print(cos(math.pi)) diff --git a/tests/float/math_constants_extra.py b/tests/float/math_constants_extra.py new file mode 100644 index 0000000000000..dea49aef5a732 --- /dev/null +++ b/tests/float/math_constants_extra.py @@ -0,0 +1,17 @@ +# Tests constants of the math module available only with MICROPY_PY_MATH_CONSTANTS. +try: + import math + from math import isnan + + math.tau +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +print(math.tau == 2.0 * math.pi) + +print(math.inf == float("inf")) +print(-math.inf == -float("inf")) + +print(isnan(math.nan)) +print(isnan(-math.nan)) diff --git a/tests/inlineasm/asmpushpop.py b/tests/inlineasm/asmpushpop.py index 74e729dfa2534..99566a7558fa4 100644 --- a/tests/inlineasm/asmpushpop.py +++ b/tests/inlineasm/asmpushpop.py @@ -6,4 +6,16 @@ def f(r0, r1, r2): pop({r1, r2}) +@micropython.asm_thumb +def g(): + b(START) + label(SUBROUTINE) + push({lr}) # push return address + mov(r0, 7) + pop({pc}) # return + label(START) + bl(SUBROUTINE) + + print(f(0, 1, 2)) +print(g()) diff --git a/tests/inlineasm/asmpushpop.py.exp b/tests/inlineasm/asmpushpop.py.exp index d00491fd7e5bb..fea32e7d83893 100644 --- a/tests/inlineasm/asmpushpop.py.exp +++ b/tests/inlineasm/asmpushpop.py.exp @@ -1 +1,2 @@ 1 +7 diff --git a/tests/micropython/const_alltypes.py b/tests/micropython/const_alltypes.py new file mode 100644 index 0000000000000..b5f36edc4fc33 --- /dev/null +++ b/tests/micropython/const_alltypes.py @@ -0,0 +1,26 @@ +# Test constant optimisation, with full range of const types. +# This test will only work when MICROPY_COMP_CONST and MICROPY_COMP_CONST_TUPLE are enabled. + +from micropython import const + +_INT = const(123) +_STR = const("str") +_BYTES = const(b"bytes") +_TUPLE = const((_INT, _STR, _BYTES)) +_TUPLE2 = const((None, False, True, ..., (), _TUPLE)) + +print(_INT) +print(_STR) +print(_BYTES) +print(_TUPLE) +print(_TUPLE2) + +x = _TUPLE +print(x is _TUPLE) +print(x is (_INT, _STR, _BYTES)) + +print(hasattr(globals(), "_INT")) +print(hasattr(globals(), "_STR")) +print(hasattr(globals(), "_BYTES")) +print(hasattr(globals(), "_TUPLE")) +print(hasattr(globals(), "_TUPLE2")) diff --git a/tests/micropython/const_alltypes.py.exp b/tests/micropython/const_alltypes.py.exp new file mode 100644 index 0000000000000..77aeffffab6ac --- /dev/null +++ b/tests/micropython/const_alltypes.py.exp @@ -0,0 +1,12 @@ +123 +str +b'bytes' +(123, 'str', b'bytes') +(None, False, True, Ellipsis, (), (123, 'str', b'bytes')) +True +True +False +False +False +False +False diff --git a/tests/micropython/extreme_exc.py b/tests/micropython/extreme_exc.py index 9d2f24745f933..ad819e408fd82 100644 --- a/tests/micropython/extreme_exc.py +++ b/tests/micropython/extreme_exc.py @@ -126,8 +126,8 @@ def f(): ) except Exception as er: e = er - lst[0][0] = None - lst = None + while lst: + lst[0], lst = None, lst[0] # unlink lists to free up heap print(repr(e)[:10]) # raise a deep exception with the heap locked diff --git a/tests/micropython/heapalloc.py b/tests/micropython/heapalloc.py index 99f157105daa9..e19f8d0255deb 100644 --- a/tests/micropython/heapalloc.py +++ b/tests/micropython/heapalloc.py @@ -33,6 +33,10 @@ def f3(a, b, c, d): print(x1, x3, x5, x7, x2 + x4 + x6 + x8) +def f4(): + return True, b"bytes", () + + global_var = 1 @@ -45,7 +49,11 @@ def test(): f1(a=i) # keyword arguments f2(i) # default arg (second one) f2(i, i) # 2 args + f1((1, "two", (b"three",))) # use a constant tuple f3(1, 2, 3, 4) # function with lots of local state + for i in 1, "two": # iterate over constant tuple + print(i) + print(f4()) # returns a constant tuple # call test() with heap allocation disabled diff --git a/tests/micropython/heapalloc.py.exp b/tests/micropython/heapalloc.py.exp index c8cffe183f074..b8580edc61c05 100644 --- a/tests/micropython/heapalloc.py.exp +++ b/tests/micropython/heapalloc.py.exp @@ -8,4 +8,8 @@ 1 1 2 1 1 +(1, 'two', (b'three',)) 1 2 3 4 10 +1 +two +(True, b'bytes', ()) diff --git a/tests/micropython/heapalloc_exc_compressed.py b/tests/micropython/heapalloc_exc_compressed.py index 79e423ca0f565..cddc0f7b4095d 100644 --- a/tests/micropython/heapalloc_exc_compressed.py +++ b/tests/micropython/heapalloc_exc_compressed.py @@ -4,13 +4,11 @@ # mp_obj_new_exception_msg_varg (exception requires decompression at raise-time to format) # mp_obj_new_exception_msg (decompression can be deferred) -# NameError uses mp_obj_new_exception_msg_varg for NameError("name '%q' isn't defined") -# set.pop uses mp_obj_new_exception_msg for KeyError("pop from an empty set") +# NameError uses mp_obj_new_exception_msg_varg for NameError("name '%q' is not defined") +# `raise 0` uses mp_obj_new_exception_msg for TypeError("exceptions must derive from BaseException") # Tests that deferred decompression works both via print(e) and accessing the message directly via e.args. -a = set() - # First test the regular case (can use heap for allocating the decompression buffer). try: name() @@ -18,8 +16,8 @@ print(type(e).__name__, e) try: - a.pop() -except KeyError as e: + raise 0 +except TypeError as e: print(type(e).__name__, e) try: @@ -28,8 +26,8 @@ print(e.args[0]) try: - a.pop() -except KeyError as e: + raise 0 +except TypeError as e: print(e.args[0]) # Then test that it still works when the heap is locked (i.e. in ISR context). @@ -41,8 +39,8 @@ print(type(e).__name__) try: - a.pop() -except KeyError as e: + raise 0 +except TypeError as e: print(type(e).__name__) micropython.heap_unlock() diff --git a/tests/micropython/heapalloc_exc_compressed.py.exp b/tests/micropython/heapalloc_exc_compressed.py.exp index e00efe088cc22..c2690353b07f2 100644 --- a/tests/micropython/heapalloc_exc_compressed.py.exp +++ b/tests/micropython/heapalloc_exc_compressed.py.exp @@ -1,6 +1,6 @@ NameError name 'name' is not defined -KeyError pop from empty set +TypeError exceptions must derive from BaseException name 'name' is not defined -pop from empty set +exceptions must derive from BaseException NameError -KeyError +TypeError diff --git a/tests/micropython/heapalloc_exc_compressed_emg_exc.py b/tests/micropython/heapalloc_exc_compressed_emg_exc.py index 86ade07862a1c..48ce9dd69e6e2 100644 --- a/tests/micropython/heapalloc_exc_compressed_emg_exc.py +++ b/tests/micropython/heapalloc_exc_compressed_emg_exc.py @@ -9,8 +9,6 @@ except AttributeError: pass -a = set() - def test(): micropython.heap_lock() @@ -21,8 +19,8 @@ def test(): print(type(e).__name__, e) try: - a.pop() - except KeyError as e: + raise 0 + except TypeError as e: print(type(e).__name__, e) try: @@ -31,8 +29,8 @@ def test(): print(e.args[0]) try: - a.pop() - except KeyError as e: + raise 0 + except TypeError as e: print(e.args[0]) micropython.heap_unlock() diff --git a/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp b/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp index 4293b45091601..c3974250d4e26 100644 --- a/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp +++ b/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp @@ -1,4 +1,4 @@ NameError name 'name' is not defined -KeyError pop from empty set +TypeError exceptions must derive from BaseException name 'name' is not defined -pop from empty set +exceptions must derive from BaseException diff --git a/tests/micropython/import_mpy_invalid.py b/tests/micropython/import_mpy_invalid.py index d497e897e1130..894fc582ce122 100644 --- a/tests/micropython/import_mpy_invalid.py +++ b/tests/micropython/import_mpy_invalid.py @@ -50,9 +50,8 @@ def open(self, path, mode): # these are the test .mpy files user_files = { "/mod0.mpy": b"", # empty file - "/mod1.mpy": b"M", # too short header - "/mod2.mpy": b"M\x00\x00\x00", # bad version - "/mod3.mpy": b"M\x00\x00\x00\x7f", # qstr window too large + "/mod1.mpy": b"C", # too short header + "/mod2.mpy": b"C\x00\x00\x00", # bad version } # create and mount a user filesystem diff --git a/tests/micropython/import_mpy_invalid.py.exp b/tests/micropython/import_mpy_invalid.py.exp index 432287028efd6..1727ea1cea56b 100644 --- a/tests/micropython/import_mpy_invalid.py.exp +++ b/tests/micropython/import_mpy_invalid.py.exp @@ -1,4 +1,3 @@ -mod0 RuntimeError Corrupt .mpy file -mod1 RuntimeError Corrupt .mpy file -mod2 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. -mod3 ValueError Incompatible .mpy file. Please update all .mpy files. See http://adafru.it/mpy-update for more info. +mod0 ValueError incompatible .mpy file +mod1 ValueError incompatible .mpy file +mod2 ValueError incompatible .mpy file diff --git a/tests/micropython/import_mpy_native_x64.py b/tests/micropython/import_mpy_native.py similarity index 53% rename from tests/micropython/import_mpy_native_x64.py rename to tests/micropython/import_mpy_native.py index c8379e177a974..0dfbca90867b4 100644 --- a/tests/micropython/import_mpy_native_x64.py +++ b/tests/micropython/import_mpy_native.py @@ -9,7 +9,8 @@ print("SKIP") raise SystemExit -if not (sys.platform == "linux" and sys.maxsize > 2**32): +mpy_arch = sys.implementation._mpy >> 8 +if mpy_arch == 0: print("SKIP") raise SystemExit @@ -49,52 +50,59 @@ def open(self, path, mode): # these are the test .mpy files +valid_header = bytes([ord("C"), 6, mpy_arch, 31]) # fmt: off user_files = { # bad architecture - '/mod0.mpy': b'C\x05\xfe\x00\x10', + '/mod0.mpy': b'C\x06\xfc\x1f', # test loading of viper and asm - '/mod1.mpy': ( - b'C\x05\x0a\x1f\x20' # header + '/mod1.mpy': valid_header + ( + b'\x02' # n_qstr + b'\x00' # n_obj - b'\x20' # n bytes, bytecode - b'\x00\x08\x02m\x02m' # prelude + b'\x0emod1.py\x00' # qstr0 = "mod1.py" + b'\x0aouter\x00' # qstr1 = "outer" + + b'\x2c' # 5 bytes, have children, bytecode + b'\x00\x02' # prelude + b'\x01' # simple name (qstr index) b'\x51' # LOAD_CONST_NONE b'\x63' # RETURN_VALUE - b'\x00\x02' # n_obj, n_raw_code + b'\x02' # 2 children - b'\x22' # n bytes, viper code - b'\x00\x00\x00\x00\x00\x00' # dummy machine code - b'\x00\x00' # qstr0 - b'\x01\x0c\x0aprint' # n_qstr, qstr0 - b'\x00\x00\x00' # scope_flags, n_obj, n_raw_code + b'\x42' # 8 bytes, no children, viper code + b'\x00\x00\x00\x00\x00\x00\x00\x00' # dummy machine code + b'\x00' # scope_flags - b'\x23' # n bytes, asm code - b'\x00\x00\x00\x00\x00\x00\x00\x00' # dummy machine code - b'\x00\x00\x00' # scope_flags, n_pos_args, type_sig + b'\x43' # 8 bytes, no children, asm code + b'\x00\x00\x00\x00\x00\x00\x00\x00' # dummy machine code + b'\x00\x00\x00' # scope_flags, n_pos_args, type_sig ), # test loading viper with additional scope flags and relocation - '/mod2.mpy': ( - b'C\x05\x0a\x1f\x20' # header + '/mod2.mpy': valid_header + ( + b'\x02' # n_qstr + b'\x00' # n_obj + + b'\x0emod2.py\x00' # qstr0 = "mod2.py" + b'\x0aouter\x00' # qstr1 = "outer" - b'\x20' # n bytes, bytecode - b'\x00\x08\x02m\x02m' # prelude + b'\x2c' # 5 bytes, have children, bytecode + b'\x00\x02' # prelude + b'\x01' # simple name (qstr index) b'\x51' # LOAD_CONST_NONE b'\x63' # RETURN_VALUE - b'\x00\x01' # n_obj, n_raw_code + b'\x01' # 1 child - b'\x12' # n bytes(=4), viper code - b'\x00\x00\x00\x00' # dummy machine code - b'\x00' # n_qstr - 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 - b'\x03\x01\x00' # dummy relocation of rodata + b'\x22' # 4 bytes, no children, viper code + b'\x00\x00\x00\x00' # dummy machine code + b'\xe0' # scope_flags: VIPERBSS | VIPERRODATA | VIPERRELOC + b'\x06\x04' # rodata=6 bytes, bss=4 bytes + b'rodata' # rodata content + b'\x03\x01\x00' # dummy relocation of rodata ), } # fmt: on diff --git a/tests/micropython/import_mpy_native.py.exp b/tests/micropython/import_mpy_native.py.exp new file mode 100644 index 0000000000000..320cac09d8c85 --- /dev/null +++ b/tests/micropython/import_mpy_native.py.exp @@ -0,0 +1,3 @@ +mod0 ValueError incompatible .mpy arch +mod1 OK +mod2 OK diff --git a/tests/micropython/import_mpy_native_gc.py b/tests/micropython/import_mpy_native_gc.py index 58291449cee6d..1234184aed33c 100644 --- a/tests/micropython/import_mpy_native_gc.py +++ b/tests/micropython/import_mpy_native_gc.py @@ -3,7 +3,7 @@ try: import gc, sys, uio, uos - sys.implementation.mpy + sys.implementation._mpy uio.IOBase uos.mount except (ImportError, AttributeError): @@ -46,24 +46,24 @@ def open(self, path, mode): # Pre-compiled examples/natmod/features0 example for various architectures, keyed -# by the required value of sys.implementation.mpy. +# by the required value of sys.implementation._mpy. features0_file_contents = { # -march=x64 - 0xA05: b'C\x05\x0a\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 \x00\x00\r \x01"\xa1\x1c\x01\x1e\xff', - # -march=armv7m - 0x1605: b"C\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>\xa18\x01:\xff", + 0x806: b'C\x06\x08\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x8a\x02\xe9/\x00\x00\x00SH\x8b\x1d\x83\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\x1dQ\x00\x00\x00H\x8bG\x08L\x8bc(H\x8bx\x08A\xff\xd4H\x8d5+\x00\x00\x00H\x89\xc5H\x8b\x059\x00\x00\x00\x0f\xb7x\x02\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\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\x00\x00\x00\x00\x00\x00\x00\x00 \x11$\r&\xa5 \x01"\xff', + # -march=armv6m + 0x1006: b'C\x06\x14\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x88"\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\xbfn\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\nN\nK~D\xf4XChgiXh\xb8G\x05F\x07K\x08I\xf2XyDP\x88ck\x98G(F\xb8G h\xf8\xbd\x00\xbf:\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x11>\r@\xa5:\x01<\xff', } -# Populate other armv7m-derived archs based on armv7m. -for arch in (0x1A05, 0x1E05, 0x2205): - features0_file_contents[arch] = features0_file_contents[0x1605] +# Populate armv7m-derived archs based on armv6m. +for arch in (0x1406, 0x1806, 0x1C06, 0x2006): + features0_file_contents[arch] = features0_file_contents[0x1006] -if sys.implementation.mpy not in features0_file_contents: +if sys.implementation._mpy not in features0_file_contents: print("SKIP") raise SystemExit # These are the test .mpy files. -user_files = {"/features0.mpy": features0_file_contents[sys.implementation.mpy]} +user_files = {"/features0.mpy": features0_file_contents[sys.implementation._mpy]} # Create and mount a user filesystem. uos.mount(UserFS(user_files), "/userfs") diff --git a/tests/micropython/import_mpy_native_x64.py.exp b/tests/micropython/import_mpy_native_x64.py.exp deleted file mode 100644 index 0b478aa77f55d..0000000000000 --- a/tests/micropython/import_mpy_native_x64.py.exp +++ /dev/null @@ -1,3 +0,0 @@ -mod0 ValueError incompatible native .mpy architecture -mod1 OK -mod2 OK diff --git a/tests/micropython/native_gen.py b/tests/micropython/native_gen.py index 7ea45b1497ab2..7e1ee25bcf452 100644 --- a/tests/micropython/native_gen.py +++ b/tests/micropython/native_gen.py @@ -25,3 +25,34 @@ def gen2(x): print(list(gen2(3))) + + +# catching an exception from .throw() +@micropython.native +def gen3(): + try: + yield 1 + yield 2 + except Exception as er: + print("caught", repr(er)) + yield 3 + + +g = gen3() +print(next(g)) +print(g.throw(ValueError(42))) + + +# responding to .close() +@micropython.native +def gen4(): + try: + yield 1 + except: + print("raising GeneratorExit") + raise GeneratorExit + + +g = gen4() +print(next(g)) +print(g.close()) diff --git a/tests/micropython/native_gen.py.exp b/tests/micropython/native_gen.py.exp index cc09e309f2aa0..fba4e558ccc8e 100644 --- a/tests/micropython/native_gen.py.exp +++ b/tests/micropython/native_gen.py.exp @@ -2,3 +2,9 @@ 4 5 [0, 1, 2] +1 +caught ValueError(42,) +3 +1 +raising GeneratorExit +None diff --git a/tests/micropython/native_while.py b/tests/micropython/native_while.py new file mode 100644 index 0000000000000..ccf0ae0e03515 --- /dev/null +++ b/tests/micropython/native_while.py @@ -0,0 +1,13 @@ +# test native while loop + + +@micropython.native +def f(n): + i = 0 + while i < n: + print(i) + i += 1 + + +f(2) +f(4) diff --git a/tests/pybnative/while.py.exp b/tests/micropython/native_while.py.exp similarity index 100% rename from tests/pybnative/while.py.exp rename to tests/micropython/native_while.py.exp diff --git a/tests/perf_bench/bm_chaos.py b/tests/perf_bench/bm_chaos.py index d0f1337db7112..e0e9269ebd367 100644 --- a/tests/perf_bench/bm_chaos.py +++ b/tests/perf_bench/bm_chaos.py @@ -218,6 +218,10 @@ def create_image_chaos(self, w, h, iterations, rng_seed): ########################################################################### # Benchmark interface +if not hasattr(random, "randrange"): + print("SKIP") + raise SystemExit + bm_params = { (100, 50): (0.25, 100, 50, 50, 50, 1234), (1000, 1000): (0.25, 200, 400, 400, 1000, 1234), diff --git a/tests/perf_bench/core_import_mpy_multi.py b/tests/perf_bench/core_import_mpy_multi.py new file mode 100644 index 0000000000000..682c36328a095 --- /dev/null +++ b/tests/perf_bench/core_import_mpy_multi.py @@ -0,0 +1,85 @@ +# Test performance of importing an .mpy file many times. + +import usys, uio, uos + +if not (hasattr(uio, "IOBase") and hasattr(uos, "mount")): + print("SKIP") + raise SystemExit + +# This is the test.py file that is compiled to test.mpy below. +""" +class A: + def __init__(self, arg): + self.arg = arg + def write(self): + pass + def read(self): + pass +def f(): + print, str, bytes, dict + Exception, ValueError, TypeError + x = "this will be a string object" + x = b"this will be a bytes object" + x = ("const tuple", None, False, True, 1, 2, 3) +result = 123 +""" +file_data = b'M\x06\x00\x1f\x14\x03\x0etest.py\x00\x0f\x02A\x00\x02f\x00\x0cresult\x00/-5#\x82I\x81{\x81w\x82/\x81\x05\x81\x17Iom\x82\x13\x06arg\x00\x05\x1cthis will be a string object\x00\x06\x1bthis will be a bytes object\x00\n\x07\x05\x0bconst tuple\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x81\\\x10\n\x01\x89\x07d`T2\x00\x10\x024\x02\x16\x022\x01\x16\x03"\x80{\x16\x04Qc\x02\x81d\x00\x08\x02(DD\x11\x05\x16\x06\x10\x02\x16\x072\x00\x16\x082\x01\x16\t2\x02\x16\nQc\x03`\x1a\x08\x08\x12\x13@\xb1\xb0\x18\x13Qc@\t\x08\t\x12` Qc@\t\x08\n\x12``Qc\x82@ \x0e\x03\x80\x08+)##\x12\x0b\x12\x0c\x12\r\x12\x0e*\x04Y\x12\x0f\x12\x10\x12\x11*\x03Y#\x00\xc0#\x01\xc0#\x02\xc0Qc' + + +class File(uio.IOBase): + def __init__(self): + self.off = 0 + + def ioctl(self, request, arg): + return 0 + + def readinto(self, buf): + buf[:] = memoryview(file_data)[self.off : self.off + len(buf)] + self.off += len(buf) + return len(buf) + + +class FS: + def mount(self, readonly, mkfs): + pass + + def chdir(self, path): + pass + + def stat(self, path): + if path == "__injected.mpy": + return tuple(0 for _ in range(10)) + else: + raise OSError(-2) # ENOENT + + def open(self, path, mode): + return File() + + +def mount(): + uos.mount(FS(), "/__remote") + uos.chdir("/__remote") + + +def test(r): + global result + for _ in r: + usys.modules.clear() + module = __import__("__injected") + result = module.result + + +########################################################################### +# Benchmark interface + +bm_params = { + (100, 10): (50,), + (1000, 10): (500,), + (5000, 10): (5000,), +} + + +def bm_setup(params): + (nloop,) = params + mount() + return lambda: test(range(nloop)), lambda: (nloop, result) diff --git a/tests/perf_bench/core_import_mpy_multi.py.exp b/tests/perf_bench/core_import_mpy_multi.py.exp new file mode 100644 index 0000000000000..190a18037c64c --- /dev/null +++ b/tests/perf_bench/core_import_mpy_multi.py.exp @@ -0,0 +1 @@ +123 diff --git a/tests/perf_bench/core_import_mpy_single.py b/tests/perf_bench/core_import_mpy_single.py new file mode 100644 index 0000000000000..af3f4a29b255e --- /dev/null +++ b/tests/perf_bench/core_import_mpy_single.py @@ -0,0 +1,135 @@ +# Test performance of importing an .mpy file just once. +# The first import of a module will intern strings that don't already exist, and +# this test should be representative of what happens in a real application. + +import uio, uos + +if not (hasattr(uio, "IOBase") and hasattr(uos, "mount")): + print("SKIP") + raise SystemExit + +# This is the test.py file that is compiled to test.mpy below. +# Many known and unknown names/strings are included to test the linking process. +""" +class A0: + def a0(self): pass + def a1(self): pass + def a2(self): pass + def a3(self): pass +class A1: + def a0(self): pass + def a1(self): pass + def a2(self): pass + def a3(self): pass +def f0(): + __call__, __class__, __delitem__, __enter__, __exit__, __getattr__, __getitem__, + __hash__, __init__, __int__, __iter__, __len__, __main__, __module__, __name__, + __new__, __next__, __qualname__, __repr__, __setitem__, __str__, + ArithmeticError, AssertionError, AttributeError, BaseException, EOFError, Ellipsis, + Exception, GeneratorExit, ImportError, IndentationError, IndexError, KeyError, + KeyboardInterrupt, LookupError, MemoryError, NameError, NoneType, + NotImplementedError, OSError, OverflowError, RuntimeError, StopIteration, + SyntaxError, SystemExit, TypeError, ValueError, ZeroDivisionError, + abs, all, any, append, args, bool, builtins, bytearray, bytecode, bytes, callable, + chr, classmethod, clear, close, const, copy, count, dict, dir, divmod, end, + endswith, eval, exec, extend, find, format, from_bytes, get, getattr, globals, + hasattr, hash, id, index, insert, int, isalpha, isdigit, isinstance, islower, + isspace, issubclass, isupper, items, iter, join, key, keys, len, list, little, + locals, lower, lstrip, main, map, micropython, next, object, open, ord, pop, + popitem, pow, print, range, read, readinto, readline, remove, replace, repr, + reverse, rfind, rindex, round, rsplit, rstrip, self, send, sep, set, setattr, + setdefault, sort, sorted, split, start, startswith, staticmethod, step, stop, str, + strip, sum, super, throw, to_bytes, tuple, type, update, upper, value, values, + write, zip, + name0, name1, name2, name3, name4, name5, name6, name7, name8, name9, + quite_a_long_name0, quite_a_long_name1, quite_a_long_name2, quite_a_long_name3, + quite_a_long_name4, quite_a_long_name5, quite_a_long_name6, quite_a_long_name7, + quite_a_long_name8, quite_a_long_name9, quite_a_long_name10, quite_a_long_name11, +def f1(): + x = "this will be a string object 0" + x = "this will be a string object 1" + x = "this will be a string object 2" + x = "this will be a string object 3" + x = "this will be a string object 4" + x = "this will be a string object 5" + x = "this will be a string object 6" + x = "this will be a string object 7" + x = "this will be a string object 8" + x = "this will be a string object 9" + x = b"this will be a bytes object 0" + x = b"this will be a bytes object 1" + x = b"this will be a bytes object 2" + x = b"this will be a bytes object 3" + x = b"this will be a bytes object 4" + x = b"this will be a bytes object 5" + x = b"this will be a bytes object 6" + x = b"this will be a bytes object 7" + x = b"this will be a bytes object 8" + x = b"this will be a bytes object 9" + x = ("const tuple 0", None, False, True, 1, 2, 3) + x = ("const tuple 1", None, False, True, 1, 2, 3) + x = ("const tuple 2", None, False, True, 1, 2, 3) + x = ("const tuple 3", None, False, True, 1, 2, 3) + x = ("const tuple 4", None, False, True, 1, 2, 3) + x = ("const tuple 5", None, False, True, 1, 2, 3) + x = ("const tuple 6", None, False, True, 1, 2, 3) + x = ("const tuple 7", None, False, True, 1, 2, 3) + x = ("const tuple 8", None, False, True, 1, 2, 3) + x = ("const tuple 9", None, False, True, 1, 2, 3) +result = 123 +""" +file_data = b"M\x06\x00\x1f\x81=\x1e\x0etest.py\x00\x0f\x04A0\x00\x04A1\x00\x04f0\x00\x04f1\x00\x0cresult\x00/-5\x04a0\x00\x04a1\x00\x04a2\x00\x04a3\x00\x13\x15\x17\x19\x1b\x1d\x1f!#%')+1379;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}\x7f\x81\x01\x81\x03\x81\x05\x81\x07\x81\t\x81\x0b\x81\r\x81\x0f\x81\x11\x81\x13\x81\x15\x81\x17\x81\x19\x81\x1b\x81\x1d\x81\x1f\x81!\x81#\x81%\x81'\x81)\x81+\x81-\x81/\x811\x813\x815\x817\x819\x81;\x81=\x81?\x81A\x81C\x81E\x81G\x81I\x81K\x81M\x81O\x81Q\x81S\x81U\x81W\x81Y\x81[\x81]\x81_\x81a\x81c\x81e\x81g\x81i\x81k\x81m\x81o\x81q\x81s\x81u\x81w\x81y\x81{\x81}\x81\x7f\x82\x01\x82\x03\x82\x05\x82\x07\x82\t\x82\x0b\x82\r\x82\x0f\x82\x11\x82\x13\x82\x15\x82\x17\x82\x19\x82\x1b\x82\x1d\x82\x1f\x82!\x82#\x82%\x82'\x82)\x82+\x82-\x82/\x821\x823\x825\x827\x829\x82;\x82=\x82?\x82A\x82E\x82G\x82I\x82K\nname0\x00\nname1\x00\nname2\x00\nname3\x00\nname4\x00\nname5\x00\nname6\x00\nname7\x00\nname8\x00\nname9\x00$quite_a_long_name0\x00$quite_a_long_name1\x00$quite_a_long_name2\x00$quite_a_long_name3\x00$quite_a_long_name4\x00$quite_a_long_name5\x00$quite_a_long_name6\x00$quite_a_long_name7\x00$quite_a_long_name8\x00$quite_a_long_name9\x00&quite_a_long_name10\x00&quite_a_long_name11\x00\x05\x1ethis will be a string object 0\x00\x05\x1ethis will be a string object 1\x00\x05\x1ethis will be a string object 2\x00\x05\x1ethis will be a string object 3\x00\x05\x1ethis will be a string object 4\x00\x05\x1ethis will be a string object 5\x00\x05\x1ethis will be a string object 6\x00\x05\x1ethis will be a string object 7\x00\x05\x1ethis will be a string object 8\x00\x05\x1ethis will be a string object 9\x00\x06\x1dthis will be a bytes object 0\x00\x06\x1dthis will be a bytes object 1\x00\x06\x1dthis will be a bytes object 2\x00\x06\x1dthis will be a bytes object 3\x00\x06\x1dthis will be a bytes object 4\x00\x06\x1dthis will be a bytes object 5\x00\x06\x1dthis will be a bytes object 6\x00\x06\x1dthis will be a bytes object 7\x00\x06\x1dthis will be a bytes object 8\x00\x06\x1dthis will be a bytes object 9\x00\n\x07\x05\rconst tuple 0\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 1\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 2\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 3\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 4\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 5\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 6\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 7\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 8\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 9\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x82d\x10\x12\x01i@i@\x84\x18\x84\x1fT2\x00\x10\x024\x02\x16\x02T2\x01\x10\x034\x02\x16\x032\x02\x16\x042\x03\x16\x05\"\x80{\x16\x06Qc\x04\x82\x0c\x00\n\x02($$$\x11\x07\x16\x08\x10\x02\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04@\t\x08\n\x81\x0b Qc@\t\x08\x0b\x81\x0b@Qc@\t\x08\x0c\x81\x0b`QcH\t\n\r\x81\x0b` Qc\x82\x14\x00\x0c\x03h`$$$\x11\x07\x16\x08\x10\x03\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04H\t\n\n\x81\x0b``QcH\t\n\x0b\x81\x0b\x80\x07QcH\t\n\x0c\x81\x0b\x80\x08QcH\t\n\r\x81\x0b\x80\tQc\xa08P:\x04\x80\x0b13///---997799<\x1f%\x1f\"\x1f%)\x1f\"//\x12\x0e\x12\x0f\x12\x10\x12\x11\x12\x12\x12\x13\x12\x14*\x07Y\x12\x15\x12\x16\x12\x17\x12\x18\x12\x19\x12\x1a\x12\x08\x12\x07*\x08Y\x12\x1b\x12\x1c\x12\t\x12\x1d\x12\x1e\x12\x1f*\x06Y\x12 \x12!\x12\"\x12#\x12$\x12%*\x06Y\x12&\x12'\x12(\x12)\x12*\x12+*\x06Y\x12,\x12-\x12.\x12/\x120*\x05Y\x121\x122\x123\x124\x125*\x05Y\x126\x127\x128\x129\x12:*\x05Y\x12;\x12<\x12=\x12>\x12?\x12@\x12A\x12B\x12C\x12D\x12E*\x0bY\x12F\x12G\x12H\x12I\x12J\x12K\x12L\x12M\x12N\x12O\x12P*\x0bY\x12Q\x12R\x12S\x12T\x12U\x12V\x12W\x12X\x12Y\x12Z*\nY\x12[\x12\\\x12]\x12^\x12_\x12`\x12a\x12b\x12c\x12d*\nY\x12e\x12f\x12g\x12h\x12i\x12j\x12k\x12l\x12m\x12n\x12o*\x0bY\x12p\x12q\x12r\x12s\x12t\x12u\x12v\x12w\x12x\x12y\x12z*\x0bY\x12{\x12|\x12}\x12~\x12\x7f\x12\x81\x00\x12\x81\x01\x12\x81\x02\x12\x81\x03\x12\x81\x04*\nY\x12\x81\x05\x12\x81\x06\x12\x81\x07\x12\x81\x08\x12\x81\t\x12\x81\n\x12\x81\x0b\x12\x81\x0c\x12\x81\r\x12\x81\x0e\x12\x81\x0f*\x0bY\x12\x81\x10\x12\x81\x11\x12\x81\x12\x12\x81\x13\x12\x81\x14\x12\x81\x15\x12\x81\x16\x12\x81\x17\x12\x81\x18\x12\x81\x19*\nY\x12\x81\x1a\x12\x81\x1b\x12\x81\x1c\x12\x81\x1d\x12\x81\x1e\x12\x81\x1f\x12\x81 \x12\x81!\x12\x81\"\x12\x81#\x12\x81$*\x0bY\x12\x81%\x12\x81&*\x02Y\x12\x81'\x12\x81(\x12\x81)\x12\x81*\x12\x81+\x12\x81,\x12\x81-\x12\x81.\x12\x81/\x12\x810*\nY\x12\x811\x12\x812\x12\x813\x12\x814*\x04Y\x12\x815\x12\x816\x12\x817\x12\x818*\x04Y\x12\x819\x12\x81:\x12\x81;\x12\x81<*\x04YQc\x87p\x08@\x05\x80###############################\x00\xc0#\x01\xc0#\x02\xc0#\x03\xc0#\x04\xc0#\x05\xc0#\x06\xc0#\x07\xc0#\x08\xc0#\t\xc0#\n\xc0#\x0b\xc0#\x0c\xc0#\r\xc0#\x0e\xc0#\x0f\xc0#\x10\xc0#\x11\xc0#\x12\xc0#\x13\xc0#\x14\xc0#\x15\xc0#\x16\xc0#\x17\xc0#\x18\xc0#\x19\xc0#\x1a\xc0#\x1b\xc0#\x1c\xc0#\x1d\xc0Qc" + + +class File(uio.IOBase): + def __init__(self): + self.off = 0 + + def ioctl(self, request, arg): + return 0 + + def readinto(self, buf): + buf[:] = memoryview(file_data)[self.off : self.off + len(buf)] + self.off += len(buf) + return len(buf) + + +class FS: + def mount(self, readonly, mkfs): + pass + + def chdir(self, path): + pass + + def stat(self, path): + if path == "__injected.mpy": + return tuple(0 for _ in range(10)) + else: + raise OSError(-2) # ENOENT + + def open(self, path, mode): + return File() + + +def mount(): + uos.mount(FS(), "/__remote") + uos.chdir("/__remote") + + +def test(): + global result + module = __import__("__injected") + result = module.result + + +########################################################################### +# Benchmark interface + +bm_params = { + (1, 1): (), +} + + +def bm_setup(params): + mount() + return lambda: test(), lambda: (1, result) diff --git a/tests/perf_bench/core_import_mpy_single.py.exp b/tests/perf_bench/core_import_mpy_single.py.exp new file mode 100644 index 0000000000000..190a18037c64c --- /dev/null +++ b/tests/perf_bench/core_import_mpy_single.py.exp @@ -0,0 +1 @@ +123 diff --git a/tests/perf_bench/core_qstr.py b/tests/perf_bench/core_qstr.py new file mode 100644 index 0000000000000..b87e2c065855a --- /dev/null +++ b/tests/perf_bench/core_qstr.py @@ -0,0 +1,21 @@ +# This tests qstr_find_strn() speed when the string being searched for is not found. + + +def test(r): + for _ in r: + str("a string that shouldn't be interned") + + +########################################################################### +# Benchmark interface + +bm_params = { + (100, 10): (400,), + (1000, 10): (4000,), + (5000, 10): (40000,), +} + + +def bm_setup(params): + (nloop,) = params + return lambda: test(range(nloop)), lambda: (nloop // 100, None) diff --git a/tests/perf_bench/core_yield_from.py b/tests/perf_bench/core_yield_from.py new file mode 100644 index 0000000000000..2f6930e2b8a5b --- /dev/null +++ b/tests/perf_bench/core_yield_from.py @@ -0,0 +1,31 @@ +# Test a deep set of "yield from" statements. + + +def recursive_yield_from(depth, iter_): + if depth <= 0: + for i in iter_: + yield i + else: + yield from recursive_yield_from(depth - 1, iter_) + + +def test(n): + global result + result = 0 + for i in recursive_yield_from(10, range(n)): + result += i + + +########################################################################### +# Benchmark interface + +bm_params = { + (100, 10): (2000,), + (1000, 10): (20000,), + (5000, 10): (100000,), +} + + +def bm_setup(params): + (nloop,) = params + return lambda: test(nloop), lambda: (nloop // 100, result) diff --git a/tests/pybnative/while.py b/tests/pybnative/while.py deleted file mode 100644 index 10625e8717247..0000000000000 --- a/tests/pybnative/while.py +++ /dev/null @@ -1,17 +0,0 @@ -import time, pyb - - -@micropython.native -def f(led, n, d): - led.off() - i = 0 - while i < n: - print(i) - led.toggle() - time.sleep_ms(d) - i += 1 - led.off() - - -f(pyb.LED(1), 2, 150) -f(pyb.LED(2), 4, 50) diff --git a/tests/qemu-arm/native_test.py b/tests/qemu-arm/native_test.py deleted file mode 100644 index 0b58433d92026..0000000000000 --- a/tests/qemu-arm/native_test.py +++ /dev/null @@ -1,5 +0,0 @@ -import native_frozen_align - -native_frozen_align.native_x(1) -native_frozen_align.native_y(2) -native_frozen_align.native_z(3) diff --git a/tests/qemu-arm/native_test.py.exp b/tests/qemu-arm/native_test.py.exp deleted file mode 100644 index dcf37cd5e2620..0000000000000 --- a/tests/qemu-arm/native_test.py.exp +++ /dev/null @@ -1,3 +0,0 @@ -2 -3 -4 diff --git a/tests/run-multitests.py b/tests/run-multitests.py index 34389e429206c..d8a4a48fa755a 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -63,10 +63,16 @@ def globals(**gs): @staticmethod def get_network_ip(): try: - import network - ip = network.WLAN().ifconfig()[0] + ip = nic.ifconfig()[0] except: - ip = "127.0.0.1" + try: + import network + if hasattr(network, "WLAN"): + ip = network.WLAN().ifconfig()[0] + else: + ip = network.LAN().ifconfig()[0] + except: + ip = HOST_IP return ip {} @@ -76,15 +82,31 @@ def get_network_ip(): """ # The btstack implementation on Unix generates some spurious output that we -# can't control. +# can't control. Also other platforms may output certain warnings/errors that +# can be safely ignored. IGNORE_OUTPUT_MATCHES = ( "libusb: error ", # It tries to open devices that it doesn't have access to (libusb prints unconditionally). "hci_transport_h2_libusb.c", # Same issue. We enable LOG_ERROR in btstack. "USB Path: ", # Hardcoded in btstack's libusb transport. "hci_number_completed_packet", # Warning from btstack. + "lld_pdu_get_tx_flush_nb HCI packet count mismatch (", # From ESP-IDF, see https://github.com/espressif/esp-idf/issues/5105 ) +def get_host_ip(_ip_cache=[]): + if not _ip_cache: + try: + import socket + + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("8.8.8.8", 80)) + _ip_cache.append(s.getsockname()[0]) + s.close() + except: + _ip_cache.append("127.0.0.1") + return _ip_cache[0] + + class PyInstance: def __init__(self): pass @@ -272,6 +294,13 @@ def run_test_on_instances(test_file, num_instances, instances): injected_globals = "" output = [[] for _ in range(num_instances)] + # If the test calls get_network_ip() then inject HOST_IP so that devices can know + # the IP address of the host. Do this lazily to not require a TCP/IP connection + # on the host if it's not needed. + with open(test_file, "rb") as f: + if b"get_network_ip" in f.read(): + injected_globals += "HOST_IP = '" + get_host_ip() + "'\n" + if cmd_args.trace_output: print("TRACE {}:".format("|".join(str(i) for i in instances))) diff --git a/tests/run-perfbench-table.py b/tests/run-perfbench-table.py new file mode 100755 index 0000000000000..3d3639e0577e2 --- /dev/null +++ b/tests/run-perfbench-table.py @@ -0,0 +1,325 @@ +#!/usr/bin/env python3 + +# This file is part of the MicroPython project, http://micropython.org/ +# The MIT License (MIT) +# Copyright (c) 2019 Damien P. George + +import os +import subprocess +import sys +import time +import argparse +from glob import glob +from rich.live import Live +from rich.console import Console +from rich.table import Table + +sys.path.append("../tools") +import pyboard + +# Paths for host executables +if os.name == "nt": + CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3.exe") + MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/windows/micropython.exe") +else: + CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") + MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/micropython") + +PYTHON_TRUTH = CPYTHON3 + +BENCH_SCRIPT_DIR = "perf_bench/" + + +def compute_stats(lst): + avg = 0 + var = 0 + for x in lst: + avg += x + var += x * x + avg /= len(lst) + var = max(0, var / len(lst) - avg**2) + return avg, var**0.5 + + +def run_script_on_target(target, script, run_command=None): + output = b"" + err = None + + if isinstance(target, pyboard.Pyboard): + # Run via pyboard interface + try: + target.enter_raw_repl() + start_ts = time.monotonic_ns() + output = target.exec_(script) + if run_command: + start_ts = time.monotonic_ns() + output = target.exec_(run_command) + end_ts = time.monotonic_ns() + except pyboard.PyboardError as er: + end_ts = time.monotonic_ns() + err = er + finally: + target.exit_raw_repl() + else: + # Run local executable + try: + if run_command: + script += run_command + start_ts = time.monotonic_ns() + p = subprocess.run( + target, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, input=script + ) + end_ts = time.monotonic_ns() + output = p.stdout + except subprocess.CalledProcessError as er: + end_ts = time.monotonic_ns() + err = er + + return str(output.strip(), "ascii"), err, (end_ts - start_ts) // 1000 + + +def run_feature_test(target, test): + with open("feature_check/" + test + ".py", "rb") as f: + script = f.read() + output, err, _ = run_script_on_target(target, script) + if err is None: + return output + else: + return "CRASH: %r" % err + + +def run_benchmark_on_target(target, script, run_command=None): + output, err, runtime_us = run_script_on_target(target, script, run_command) + if err is None: + time, norm, result = output.split(None, 2) + try: + return int(time), int(norm), result, runtime_us + except ValueError: + return -1, -1, "CRASH: %r" % output, runtime_us + else: + return -1, -1, "CRASH: %r" % err, runtime_us + + +def run_benchmarks(console, target, param_n, param_m, n_average, test_list): + skip_complex = run_feature_test(target, "complex") != "complex" + skip_native = run_feature_test(target, "native_check") != "native" + + table = Table(show_header=True) + table.add_column("Test") + table.add_column("Time", justify="right") + table.add_column("Score", justify="right") + table.add_column("Ref Time", justify="right") + + live = Live(table, console=console) + live.start() + + for test_file in sorted(test_list): + # print(test_file + ": ", end="") + + # Check if test should be skipped + skip = ( + skip_complex + and test_file.find("bm_fft") != -1 + or skip_native + and test_file.find("viper_") != -1 + ) + if skip: + print("skip") + table.add_row(test_file, *(["skip"] * 6)) + continue + + # Create test script + with open(test_file, "rb") as f: + test_script = f.read() + with open(BENCH_SCRIPT_DIR + "benchrun.py", "rb") as f: + test_script += f.read() + bm_run = b"bm_run(%u, %u)\n" % (param_n, param_m) + + # Write full test script if needed + if 0: + with open("%s.full" % test_file, "wb") as f: + f.write(test_script) + + # Run MicroPython a given number of times + times = [] + runtimes = [] + scores = [] + error = None + result_out = None + for _ in range(n_average): + self_time, norm, result, runtime_us = run_benchmark_on_target( + target, test_script, bm_run + ) + if self_time < 0 or norm < 0: + error = result + break + if result_out is None: + result_out = result + elif result != result_out: + error = "FAIL self" + break + times.append(self_time) + runtimes.append(runtime_us) + scores.append(1e6 * norm / self_time) + + # Check result against truth if needed + if error is None and result_out != "None": + _, _, result_exp, _ = run_benchmark_on_target(PYTHON_TRUTH, test_script, bm_run) + if result_out != result_exp: + error = "FAIL truth" + + if error is not None: + print(test_file, error) + if error == "no matching params": + table.add_row(test_file, *([None] * 3)) + else: + table.add_row(test_file, *(["error"] * 3)) + else: + t_avg, t_sd = compute_stats(times) + r_avg, r_sd = compute_stats(runtimes) + s_avg, s_sd = compute_stats(scores) + # print( + # "{:.2f} {:.4f} {:.2f} {:.4f} {:.2f} {:.4f}".format( + # t_avg, 100 * t_sd / t_avg, s_avg, 100 * s_sd / s_avg, r_avg, 100 * r_sd / r_avg + # ) + # ) + table.add_row( + test_file, + f"{t_avg:.2f}±{100 * t_sd / t_avg:.1f}%", + f"{s_avg:.2f}±{100 * s_sd / s_avg:.1f}%", + f"{r_avg:.2f}±{100 * r_sd / r_avg:.1f}%", + ) + if 0: + print(" times: ", times) + print(" scores:", scores) + + live.update(table, refresh=True) + live.stop() + + +def parse_output(filename): + with open(filename) as f: + params = f.readline() + n, m, _ = params.strip().split() + n = int(n.split("=")[1]) + m = int(m.split("=")[1]) + data = [] + for l in f: + if l.find(": ") != -1 and l.find(": skip") == -1 and l.find("CRASH: ") == -1: + name, values = l.strip().split(": ") + values = tuple(float(v) for v in values.split()) + data.append((name,) + values) + return n, m, data + + +def compute_diff(file1, file2, diff_score): + # Parse output data from previous runs + n1, m1, d1 = parse_output(file1) + n2, m2, d2 = parse_output(file2) + + # Print header + if diff_score: + print("diff of scores (higher is better)") + else: + print("diff of microsecond times (lower is better)") + if n1 == n2 and m1 == m2: + hdr = "N={} M={}".format(n1, m1) + else: + hdr = "N={} M={} vs N={} M={}".format(n1, m1, n2, m2) + print( + "{:24} {:>10} -> {:>10} {:>10} {:>7}% (error%)".format( + hdr, file1, file2, "diff", "diff" + ) + ) + + # Print entries + while d1 and d2: + if d1[0][0] == d2[0][0]: + # Found entries with matching names + entry1 = d1.pop(0) + entry2 = d2.pop(0) + name = entry1[0].rsplit("/")[-1] + av1, sd1 = entry1[1 + 2 * diff_score], entry1[2 + 2 * diff_score] + av2, sd2 = entry2[1 + 2 * diff_score], entry2[2 + 2 * diff_score] + sd1 *= av1 / 100 # convert from percent sd to absolute sd + sd2 *= av2 / 100 # convert from percent sd to absolute sd + av_diff = av2 - av1 + sd_diff = (sd1**2 + sd2**2) ** 0.5 + percent = 100 * av_diff / av1 + percent_sd = 100 * sd_diff / av1 + print( + "{:24} {:10.2f} -> {:10.2f} : {:+10.2f} = {:+7.3f}% (+/-{:.2f}%)".format( + name, av1, av2, av_diff, percent, percent_sd + ) + ) + elif d1[0][0] < d2[0][0]: + d1.pop(0) + else: + d2.pop(0) + + +def main(): + cmd_parser = argparse.ArgumentParser(description="Run benchmarks for MicroPython") + cmd_parser.add_argument( + "-t", "--diff-time", action="store_true", help="diff time outputs from a previous run" + ) + cmd_parser.add_argument( + "-s", "--diff-score", action="store_true", help="diff score outputs from a previous run" + ) + cmd_parser.add_argument( + "-p", "--pyboard", action="store_true", help="run tests via pyboard.py" + ) + cmd_parser.add_argument( + "-d", "--device", default="/dev/ttyACM0", help="the device for pyboard.py" + ) + cmd_parser.add_argument("-a", "--average", default="8", help="averaging number") + cmd_parser.add_argument( + "--emit", default="bytecode", help="MicroPython emitter to use (bytecode or native)" + ) + cmd_parser.add_argument("N", nargs=1, help="N parameter (approximate target CPU frequency)") + cmd_parser.add_argument("M", nargs=1, help="M parameter (approximate target heap in kbytes)") + cmd_parser.add_argument("files", nargs="*", help="input test files") + args = cmd_parser.parse_args() + + if args.diff_time or args.diff_score: + compute_diff(args.N[0], args.M[0], args.diff_score) + sys.exit(0) + + # N, M = 50, 25 # esp8266 + # N, M = 100, 100 # pyboard, esp32 + # N, M = 1000, 1000 # PC + N = int(args.N[0]) + M = int(args.M[0]) + n_average = int(args.average) + + if args.pyboard: + target = pyboard.Pyboard(args.device) + target.enter_raw_repl() + else: + target = [MICROPYTHON, "-X", "emit=" + args.emit] + + if len(args.files) == 0: + tests_skip = ("benchrun.py",) + if M <= 25: + # These scripts are too big to be compiled by the target + tests_skip += ("bm_chaos.py", "bm_hexiom.py", "misc_raytrace.py") + tests = sorted( + BENCH_SCRIPT_DIR + test_file + for test_file in os.listdir(BENCH_SCRIPT_DIR) + if test_file.endswith(".py") and test_file not in tests_skip + ) + else: + tests = sorted(args.files) + + console = Console() + print("N={} M={} n_average={}".format(N, M, n_average)) + + run_benchmarks(console, target, N, M, n_average, tests) + + if isinstance(target, pyboard.Pyboard): + target.exit_raw_repl() + target.close() + + +if __name__ == "__main__": + main() diff --git a/tests/run-perfbench.py b/tests/run-perfbench.py index 3d3639e0577e2..a2e9e8079ad59 100755 --- a/tests/run-perfbench.py +++ b/tests/run-perfbench.py @@ -7,16 +7,14 @@ import os import subprocess import sys -import time import argparse from glob import glob -from rich.live import Live -from rich.console import Console -from rich.table import Table sys.path.append("../tools") import pyboard +prepare_script_for_target = __import__("run-tests").prepare_script_for_target + # Paths for host executables if os.name == "nt": CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3.exe") @@ -41,7 +39,7 @@ def compute_stats(lst): return avg, var**0.5 -def run_script_on_target(target, script, run_command=None): +def run_script_on_target(target, script): output = b"" err = None @@ -49,72 +47,53 @@ def run_script_on_target(target, script, run_command=None): # Run via pyboard interface try: target.enter_raw_repl() - start_ts = time.monotonic_ns() output = target.exec_(script) - if run_command: - start_ts = time.monotonic_ns() - output = target.exec_(run_command) - end_ts = time.monotonic_ns() except pyboard.PyboardError as er: - end_ts = time.monotonic_ns() err = er - finally: - target.exit_raw_repl() else: # Run local executable try: - if run_command: - script += run_command - start_ts = time.monotonic_ns() p = subprocess.run( target, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, input=script ) - end_ts = time.monotonic_ns() output = p.stdout except subprocess.CalledProcessError as er: - end_ts = time.monotonic_ns() err = er - return str(output.strip(), "ascii"), err, (end_ts - start_ts) // 1000 + return str(output.strip(), "ascii"), err def run_feature_test(target, test): with open("feature_check/" + test + ".py", "rb") as f: script = f.read() - output, err, _ = run_script_on_target(target, script) + output, err = run_script_on_target(target, script) if err is None: return output else: return "CRASH: %r" % err -def run_benchmark_on_target(target, script, run_command=None): - output, err, runtime_us = run_script_on_target(target, script, run_command) +def run_benchmark_on_target(target, script): + output, err = run_script_on_target(target, script) if err is None: + if output == "SKIP": + return -1, -1, "SKIP" time, norm, result = output.split(None, 2) try: - return int(time), int(norm), result, runtime_us + return int(time), int(norm), result except ValueError: - return -1, -1, "CRASH: %r" % output, runtime_us + return -1, -1, "CRASH: %r" % output else: - return -1, -1, "CRASH: %r" % err, runtime_us + return -1, -1, "CRASH: %r" % err -def run_benchmarks(console, target, param_n, param_m, n_average, test_list): +def run_benchmarks(args, target, param_n, param_m, n_average, test_list): skip_complex = run_feature_test(target, "complex") != "complex" skip_native = run_feature_test(target, "native_check") != "native" - - table = Table(show_header=True) - table.add_column("Test") - table.add_column("Time", justify="right") - table.add_column("Score", justify="right") - table.add_column("Ref Time", justify="right") - - live = Live(table, console=console) - live.start() + target_had_error = False for test_file in sorted(test_list): - # print(test_file + ": ", end="") + print(test_file + ": ", end="") # Check if test should be skipped skip = ( @@ -124,8 +103,7 @@ def run_benchmarks(console, target, param_n, param_m, n_average, test_list): and test_file.find("viper_") != -1 ) if skip: - print("skip") - table.add_row(test_file, *(["skip"] * 6)) + print("SKIP") continue # Create test script @@ -133,24 +111,30 @@ def run_benchmarks(console, target, param_n, param_m, n_average, test_list): test_script = f.read() with open(BENCH_SCRIPT_DIR + "benchrun.py", "rb") as f: test_script += f.read() - bm_run = b"bm_run(%u, %u)\n" % (param_n, param_m) + test_script += b"bm_run(%u, %u)\n" % (param_n, param_m) # Write full test script if needed if 0: with open("%s.full" % test_file, "wb") as f: f.write(test_script) + # Process script through mpy-cross if needed + if isinstance(target, pyboard.Pyboard) or args.via_mpy: + crash, test_script_target = prepare_script_for_target(args, script_text=test_script) + if crash: + print("CRASH:", test_script_target) + continue + else: + test_script_target = test_script + # Run MicroPython a given number of times times = [] - runtimes = [] scores = [] error = None result_out = None for _ in range(n_average): - self_time, norm, result, runtime_us = run_benchmark_on_target( - target, test_script, bm_run - ) - if self_time < 0 or norm < 0: + time, norm, result = run_benchmark_on_target(target, test_script_target) + if time < 0 or norm < 0: error = result break if result_out is None: @@ -158,43 +142,41 @@ def run_benchmarks(console, target, param_n, param_m, n_average, test_list): elif result != result_out: error = "FAIL self" break - times.append(self_time) - runtimes.append(runtime_us) - scores.append(1e6 * norm / self_time) + times.append(time) + scores.append(1e6 * norm / time) # Check result against truth if needed if error is None and result_out != "None": - _, _, result_exp, _ = run_benchmark_on_target(PYTHON_TRUTH, test_script, bm_run) + test_file_expected = test_file + ".exp" + if os.path.isfile(test_file_expected): + # Expected result is given by a file, so read that in + with open(test_file_expected) as f: + result_exp = f.read().strip() + else: + # Run CPython to work out the expected result + _, _, result_exp = run_benchmark_on_target(PYTHON_TRUTH, test_script) if result_out != result_exp: error = "FAIL truth" if error is not None: - print(test_file, error) - if error == "no matching params": - table.add_row(test_file, *([None] * 3)) - else: - table.add_row(test_file, *(["error"] * 3)) + if not error.startswith("SKIP"): + target_had_error = True + print(error) else: t_avg, t_sd = compute_stats(times) - r_avg, r_sd = compute_stats(runtimes) s_avg, s_sd = compute_stats(scores) - # print( - # "{:.2f} {:.4f} {:.2f} {:.4f} {:.2f} {:.4f}".format( - # t_avg, 100 * t_sd / t_avg, s_avg, 100 * s_sd / s_avg, r_avg, 100 * r_sd / r_avg - # ) - # ) - table.add_row( - test_file, - f"{t_avg:.2f}±{100 * t_sd / t_avg:.1f}%", - f"{s_avg:.2f}±{100 * s_sd / s_avg:.1f}%", - f"{r_avg:.2f}±{100 * r_sd / r_avg:.1f}%", + print( + "{:.2f} {:.4f} {:.2f} {:.4f}".format( + t_avg, 100 * t_sd / t_avg, s_avg, 100 * s_sd / s_avg + ) ) if 0: print(" times: ", times) print(" scores:", scores) - live.update(table, refresh=True) - live.stop() + sys.stdout.flush() + + return target_had_error def parse_output(filename): @@ -205,7 +187,7 @@ def parse_output(filename): m = int(m.split("=")[1]) data = [] for l in f: - if l.find(": ") != -1 and l.find(": skip") == -1 and l.find("CRASH: ") == -1: + if l.find(": ") != -1 and l.find(": SKIP") == -1 and l.find("CRASH: ") == -1: name, values = l.strip().split(": ") values = tuple(float(v) for v in values.split()) data.append((name,) + values) @@ -227,7 +209,7 @@ def compute_diff(file1, file2, diff_score): else: hdr = "N={} M={} vs N={} M={}".format(n1, m1, n2, m2) print( - "{:24} {:>10} -> {:>10} {:>10} {:>7}% (error%)".format( + "{:26} {:>10} -> {:>10} {:>10} {:>7}% (error%)".format( hdr, file1, file2, "diff", "diff" ) ) @@ -248,7 +230,7 @@ def compute_diff(file1, file2, diff_score): percent = 100 * av_diff / av1 percent_sd = 100 * sd_diff / av1 print( - "{:24} {:10.2f} -> {:10.2f} : {:+10.2f} = {:+7.3f}% (+/-{:.2f}%)".format( + "{:26} {:10.2f} -> {:10.2f} : {:+10.2f} = {:+7.3f}% (+/-{:.2f}%)".format( name, av1, av2, av_diff, percent, percent_sd ) ) @@ -276,6 +258,8 @@ def main(): cmd_parser.add_argument( "--emit", default="bytecode", help="MicroPython emitter to use (bytecode or native)" ) + cmd_parser.add_argument("--via-mpy", action="store_true", help="compile code to .mpy first") + cmd_parser.add_argument("--mpy-cross-flags", default="", help="flags to pass to mpy-cross") cmd_parser.add_argument("N", nargs=1, help="N parameter (approximate target CPU frequency)") cmd_parser.add_argument("M", nargs=1, help="M parameter (approximate target heap in kbytes)") cmd_parser.add_argument("files", nargs="*", help="input test files") @@ -293,6 +277,8 @@ def main(): n_average = int(args.average) if args.pyboard: + if not args.mpy_cross_flags: + args.mpy_cross_flags = "-march=armv7m" target = pyboard.Pyboard(args.device) target.enter_raw_repl() else: @@ -311,15 +297,17 @@ def main(): else: tests = sorted(args.files) - console = Console() print("N={} M={} n_average={}".format(N, M, n_average)) - run_benchmarks(console, target, N, M, n_average, tests) + target_had_error = run_benchmarks(args, target, N, M, n_average, tests) if isinstance(target, pyboard.Pyboard): target.exit_raw_repl() target.close() + if target_had_error: + sys.exit(1) + if __name__ == "__main__": main() diff --git a/tests/run-tests.py b/tests/run-tests.py index c756729ff9f74..45b4ebf5366ea 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -203,16 +203,8 @@ def send_get(what): rm_f(mpy_filename) else: - # run on pyboard - pyb.enter_raw_repl() - try: - output_mupy = pyb.execfile(test_file) - except pyboard.PyboardError as e: - had_crash = True - if not is_special and e.args[0] == "exception": - output_mupy = e.args[1] + e.args[2] + b"CRASH" - else: - output_mupy = bytes(e.args[0], "ascii") + b"\nCRASH" + # run via pyboard interface + had_crash, output_mupy = run_script_on_remote_target(pyb, args, test_file, is_special) # canonical form for all ports/platforms is to use \n for end-of-line output_mupy = output_mupy.replace(b"\r\n", b"\n") @@ -436,7 +428,6 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): if upy_float_precision < 64: skip_tests.add("float/float_divmod.py") # tested by float/float_divmod_relaxed.py instead skip_tests.add("float/float2int_doubleprec_intbig.py") - skip_tests.add("float/float_format_ints_doubleprec.py") skip_tests.add("float/float_parse_doubleprec.py") if not has_complex: @@ -492,6 +483,10 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): for t in tests: if t.startswith("basics/io_"): skip_tests.add(t) + elif args.target == "renesas-ra": + skip_tests.add( + "extmod/utime_time_ns.py" + ) # RA fsp rtc function doesn't support nano sec info elif args.target == "qemu-arm": skip_tests.add("misc/print_exception.py") # requires sys stdfiles @@ -520,6 +515,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): skip_tests.add("basics/del_local.py") # requires checking for unbound local skip_tests.add("basics/exception_chain.py") # raise from is not supported skip_tests.add("basics/scope_implicit.py") # requires checking for unbound local + skip_tests.add("basics/sys_tracebacklimit.py") # requires traceback info skip_tests.add("basics/try_finally_return2.py") # requires raise_varargs skip_tests.add("basics/unboundlocal.py") # requires checking for unbound local skip_tests.update( @@ -538,6 +534,9 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): "misc/print_exception.py" ) # because native doesn't have proper traceback info skip_tests.add("misc/sys_exc_info.py") # sys.exc_info() is not supported for native + skip_tests.add("misc/sys_settrace_features.py") # sys.settrace() not supported + skip_tests.add("misc/sys_settrace_generator.py") # sys.settrace() not supported + skip_tests.add("misc/sys_settrace_loop.py") # sys.settrace() not supported skip_tests.add( "micropython/emg_exc.py" ) # because native doesn't have proper traceback info @@ -548,6 +547,7 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): "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("stress/bytecode_limit.py") # bytecode specific test def run_one_test(test_file): test_file = test_file.replace("\\", "/") @@ -571,7 +571,7 @@ def run_one_test(test_file): is_endian = test_name.endswith("_endian") is_int_big = test_name.startswith("int_big") or test_name.endswith("_intbig") is_bytearray = test_name.startswith("bytearray") or test_name.endswith("_bytearray") - is_set_type = test_name.startswith("set_") or test_name.startswith("frozenset") + is_set_type = test_name.startswith(("set_", "frozenset")) or test_name.endswith("_set") is_slice = test_name.find("slice") != -1 or test_name in misc_slice_tests is_async = test_name.startswith(("async_", "uasyncio_")) is_const = test_name.startswith("const") @@ -818,7 +818,16 @@ def main(): "unix", "qemu-arm", ) - EXTERNAL_TARGETS = ("pyboard", "wipy", "esp8266", "esp32", "minimal", "nrf") + EXTERNAL_TARGETS = ( + "pyboard", + "wipy", + "esp8266", + "esp32", + "minimal", + "nrf", + "renesas-ra", + "rp2", + ) if args.target in LOCAL_TARGETS or args.list_tests: pyb = None elif args.target in EXTERNAL_TARGETS: @@ -826,6 +835,18 @@ def main(): sys.path.append(base_path("../tools")) import pyboard + if not args.mpy_cross_flags: + if args.target == "esp8266": + args.mpy_cross_flags = "-march=xtensa" + elif args.target == "esp32": + args.mpy_cross_flags = "-march=xtensawin" + elif args.target == "rp2": + args.mpy_cross_flags = "-march=armv6m" + elif args.target == "pyboard": + args.mpy_cross_flags = "-march=armv7emsp" + else: + args.mpy_cross_flags = "-march=armv7m" + pyb = pyboard.Pyboard(args.device, args.baudrate, args.user, args.password) pyb.enter_raw_repl() else: @@ -842,7 +863,11 @@ def main(): ) if args.target == "pyboard": # run pyboard tests - test_dirs += ("float", "stress", "pyb", "pybnative", "inlineasm") + test_dirs += ("float", "stress", "pyb", "inlineasm") + elif args.target in ("renesas-ra"): + test_dirs += ("float", "inlineasm", "renesas-ra") + elif args.target == "rp2": + test_dirs += ("float", "stress", "inlineasm") elif args.target in ("esp8266", "esp32", "minimal", "nrf"): test_dirs += ("float",) elif args.target == "wipy": diff --git a/tests/stress/bytecode_limit.py b/tests/stress/bytecode_limit.py new file mode 100644 index 0000000000000..8cca413cf2777 --- /dev/null +++ b/tests/stress/bytecode_limit.py @@ -0,0 +1,36 @@ +# Test the limits of bytecode generation. + +body = " with f()()() as a:\n try:\n f()()()\n except Exception:\n pass\n" + +# Test overflow of jump offset. +for n in (430, 431, 432, 433): + try: + exec("cond = 0\nif cond:\n" + body * n + "else:\n print('cond false')\n") + except MemoryError: + print("SKIP") + raise SystemExit + except RuntimeError: + print("RuntimeError") + +# Test changing size of code info (source line/bytecode mapping) due to changing +# bytecode size in the final passes. This test is very specific to how the +# code info is encoded, and how jump offsets shrink in the final passes. This +# test should fail if the bytecode emitter doesn't correctly handle shrinking of +# the code info section. +exec( + """ +x = 0 +if x: +""" + + body * 13 + + """ +x = [1 if x else 123] + + + + + + +print(x) +""" +) diff --git a/tests/stress/bytecode_limit.py.exp b/tests/stress/bytecode_limit.py.exp new file mode 100644 index 0000000000000..74ab06c09b674 --- /dev/null +++ b/tests/stress/bytecode_limit.py.exp @@ -0,0 +1,5 @@ +cond false +cond false +RuntimeError +RuntimeError +[123] diff --git a/tests/stress/fun_call_limit.py b/tests/stress/fun_call_limit.py new file mode 100644 index 0000000000000..b802aadd558c0 --- /dev/null +++ b/tests/stress/fun_call_limit.py @@ -0,0 +1,36 @@ +# Test the limit of the number of arguments to a function call. +# This currently tests the case of *args after many positional args. + + +def f(*args): + return len(args) + + +def test(n): + pos_args = ",".join(str(i) for i in range(n)) + s = "f({}, *(100, 101), 102, 103)".format(pos_args) + try: + return eval(s) + except SyntaxError: + return "SyntaxError" + + +# If the port has at least 32-bits then this test should pass. +print(test(29)) + +# This test should fail on all ports (overflows a small int). +print(test(70)) + +# Check that there is a correct transition to the limit of too many args before *args. +reached_limit = False +for i in range(30, 70): + result = test(i) + if reached_limit: + if result != "SyntaxError": + print("FAIL") + else: + if result == "SyntaxError": + reached_limit = True + else: + if result != i + 4: + print("FAIL") diff --git a/tests/stress/fun_call_limit.py.exp b/tests/stress/fun_call_limit.py.exp new file mode 100644 index 0000000000000..53d2b28043015 --- /dev/null +++ b/tests/stress/fun_call_limit.py.exp @@ -0,0 +1,2 @@ +33 +SyntaxError diff --git a/tests/thread/stress_aes.py b/tests/thread/stress_aes.py index 199fe3c88ce3c..0ff5544aa8800 100644 --- a/tests/thread/stress_aes.py +++ b/tests/thread/stress_aes.py @@ -271,7 +271,11 @@ def thread_entry(n_loop): if __name__ == "__main__": import sys - if sys.platform == "rp2": + if hasattr(sys, "settrace"): + # Builds with sys.settrace enabled are slow, so make the test short. + n_thread = 2 + n_loop = 2 + elif sys.platform == "rp2": n_thread = 1 n_loop = 2 elif sys.platform in ("esp32", "pyboard"): diff --git a/tests/unix/extra_coverage.py b/tests/unix/extra_coverage.py index 8ea27cbf2f801..bb22485026e89 100644 --- a/tests/unix/extra_coverage.py +++ b/tests/unix/extra_coverage.py @@ -89,6 +89,9 @@ except ZeroDivisionError: print("ZeroDivisionError") +# test importing various objects +import frzmpy3 + # test for MP_QSTR_NULL regression from frzqstr import returns_NULL diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index 0711da6a22885..b9742461e42b5 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -17,6 +17,25 @@ abc # GC 0x0 0x0 +# tracked allocation +m_tracked_head = 0x0 +0 1 +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +0 1 +1 1 +2 1 +3 1 +4 1 +5 1 +6 1 +7 1 +m_tracked_head = 0x0 # vstr tests sts @@ -29,30 +48,29 @@ RuntimeError: ame__ mport -builtins micropython __future__ _asyncio -_thread _uasyncio aesio array -audiocore audiomixer binascii bitmaptools -btree cexample cmath collections -cppexample displayio errno ffi -framebuf gc hashlib json -math qrio rainbowio re -struct synthio sys termios -traceback ubinascii uctypes uerrno -uheapq uio ujson ulab -ulab.numpy ulab.numpy.fft ulab.numpy.linalg -ulab.scipy ulab.scipy.linalg -ulab.scipy.optimize ulab.scipy.signal -ulab.scipy.special ulab.utils uos -urandom ure uselect utime -utimeq uzlib zlib +builtins micropython __future__ _thread +_uasyncio aesio array audiocore +audiomixer bitmaptools cexample cmath +collections cppexample displayio gc +math qrio rainbowio struct +synthio termios traceback ubinascii +uctypes uerrno uhashlib uheapq +uio ujson ulab ulab.numpy +ulab.numpy.fft ulab.numpy.linalg ulab.scipy +ulab.scipy.linalg ulab.scipy.optimize +ulab.scipy.signal ulab.scipy.special +ulab.utils uos urandom ure +uselect usys utime utimeq +uzlib zlib ime utime utimeq argv atexit byteorder exc_info exit getsizeof implementation maxsize -modules path platform stderr -stdin stdout version version_info +modules path platform print_exception +ps1 ps2 stderr stdin +stdout tracebacklimit version version_info ementation # attrtuple (start=1, stop=2, step=3) @@ -180,4 +198,9 @@ frzstr_pkg2.mod frzmpy_pkg2.mod 1 ZeroDivisionError +\ + +X +'\x1b' +b'\x00\xff' NULL diff --git a/tools/analyze_heap_dump.py b/tools/analyze_heap_dump.py index ede990929d0c6..18da11c456ff2 100755 --- a/tools/analyze_heap_dump.py +++ b/tools/analyze_heap_dump.py @@ -288,10 +288,6 @@ def load_pointer(address): dynamic_type = 0x40000000 # placeholder, doesn't match any memory - long_lived_start = load_pointer( - mp_state_ctx + 272 - ) # (gdb) p &mp_state_ctx.mem.gc_lowest_long_lived_ptr - type_colors = { dict_type: "red", property_type: "yellow", @@ -368,10 +364,7 @@ def save_allocated_block(end, current_allocation): potential_type = None node = ownership_graph.get_node(address) node.attr["height"] = 0.25 * current_allocation - if address >= long_lived_start: - node.attr["fontcolor"] = "hotpink" - else: - node.attr["fontcolor"] = "black" + node.attr["fontcolor"] = "black" block_data[address] = data for k in range(len(data) // 4): word = struct.unpack_from("".join(wrapped) ) node.attr["fontname"] = "FiraCode-Bold" - if block >= long_lived_start: - node.attr["fontcolor"] = "hotpink" - else: - node.attr["fontcolor"] = "black" + node.attr["fontcolor"] = "black" node.attr["fontpath"] = "/Users/tannewt/Library/Fonts/" node.attr["fontsize"] = 8 diff --git a/tools/analyze_mpy.py b/tools/analyze_mpy.py index 8c2056e03019f..3f212e2679188 100755 --- a/tools/analyze_mpy.py +++ b/tools/analyze_mpy.py @@ -316,8 +316,8 @@ class mpyFile: def __init__(self, encoded_mpy): # this matches mp-raw_code_save in py/persistentcode.c first_byte = encoded_mpy.read(1) - if first_byte != b"M": - raise ValueError("Not a valid first byte. Should be 'M' but is {}".format(first_byte)) + if first_byte != b"C": + raise ValueError("Not a valid first byte. Should be 'C' but is {}".format(first_byte)) self.version = encoded_mpy.read(1)[0] self.feature_flags = encoded_mpy.read(1)[0] self.small_int_bits = encoded_mpy.read(1)[0] diff --git a/tools/autobuild/build-boards.sh b/tools/autobuild/build-boards.sh index 4b5259b667ab6..9caadc1b07ac0 100755 --- a/tools/autobuild/build-boards.sh +++ b/tools/autobuild/build-boards.sh @@ -30,8 +30,8 @@ function build_board { dest=$dest_dir/$descr$fw_tag.$ext if [ -r $build_dir/firmware.$ext ]; then mv $build_dir/firmware.$ext $dest - else - # esp32 has micropython.elf and micropython.map + elif [ -r $build_dir/micropython.$ext ]; then + # esp32 has micropython.elf, etc mv $build_dir/micropython.$ext $dest fi done @@ -93,7 +93,7 @@ function build_esp32_boards { else if [ $mcu != esp32 ]; then # build esp32-s2/s3/c3 based boards with IDF v4.4+ - build_board $board_json $fw_tag $dest_dir bin elf map + build_board $board_json $fw_tag $dest_dir bin elf map uf2 fi fi done @@ -103,6 +103,10 @@ function build_mimxrt_boards { build_boards modmimxrt.c $1 $2 bin hex } +function build_renesas_ra_boards { + build_boards ra_it.c $1 $2 hex +} + function build_rp2_boards { build_boards modrp2.c $1 $2 uf2 } diff --git a/tools/ci.sh b/tools/ci.sh new file mode 100755 index 0000000000000..72e779c499d29 --- /dev/null +++ b/tools/ci.sh @@ -0,0 +1,699 @@ +#!/bin/bash + +if which nproc > /dev/null; then + MAKEOPTS="-j$(nproc)" +else + MAKEOPTS="-j$(sysctl -n hw.ncpu)" +fi + +######################################################################################## +# general helper functions + +function ci_gcc_arm_setup { + sudo apt-get install gcc-arm-none-eabi libnewlib-arm-none-eabi + arm-none-eabi-gcc --version +} + +######################################################################################## +# code formatting + +function ci_code_formatting_setup { + sudo apt-add-repository --yes --update ppa:pybricks/ppa + sudo apt-get install uncrustify + pip3 install black + uncrustify --version + black --version +} + +function ci_code_formatting_run { + tools/codeformat.py -v +} + +######################################################################################## +# commit formatting + +function ci_commit_formatting_run { + git remote add upstream https://github.com/micropython/micropython.git + git fetch --depth=100 upstream master + # For a PR, upstream/master..HEAD ends with a merge commit into master, exclude that one. + tools/verifygitlog.py -v upstream/master..HEAD --no-merges +} + +######################################################################################## +# code size + +function ci_code_size_setup { + sudo apt-get update + sudo apt-get install gcc-multilib + gcc --version + ci_gcc_arm_setup +} + +function ci_code_size_build { + # starts off at either the ref/pull/N/merge FETCH_HEAD, or the current branch HEAD + git checkout -b pull_request # save the current location + git remote add upstream https://github.com/micropython/micropython.git + git fetch --depth=100 upstream master + # build reference, save to size0 + # ignore any errors with this build, in case master is failing + git checkout `git merge-base --fork-point upstream/master pull_request` + git show -s + tools/metrics.py clean bm + tools/metrics.py build bm | tee ~/size0 || true + # build PR/branch, save to size1 + git checkout pull_request + git log upstream/master..HEAD + tools/metrics.py clean bm + tools/metrics.py build bm | tee ~/size1 +} + +######################################################################################## +# .mpy file format + +function ci_mpy_format_setup { + sudo pip3 install pyelftools +} + +function ci_mpy_format_test { + # Test mpy-tool.py dump feature on bytecode + python2 ./tools/mpy-tool.py -xd ports/minimal/frozentest.mpy + python3 ./tools/mpy-tool.py -xd ports/minimal/frozentest.mpy + + # Test mpy-tool.py dump feature on native code + make -C examples/natmod/features1 + ./tools/mpy-tool.py -xd examples/natmod/features1/features1.mpy +} + +######################################################################################## +# ports/cc3200 + +function ci_cc3200_setup { + ci_gcc_arm_setup +} + +function ci_cc3200_build { + make ${MAKEOPTS} -C ports/cc3200 BTARGET=application BTYPE=release + make ${MAKEOPTS} -C ports/cc3200 BTARGET=bootloader BTYPE=release +} + +######################################################################################## +# ports/esp32 + +function ci_esp32_setup_helper { + pip3 install pyelftools + git clone https://github.com/espressif/esp-idf.git + git -C esp-idf checkout $1 + git -C esp-idf submodule update --init \ + components/bt/host/nimble/nimble \ + components/esp_wifi \ + components/esptool_py/esptool \ + components/lwip/lwip \ + components/mbedtls/mbedtls + if [ -d esp-idf/components/bt/controller/esp32 ]; then + git -C esp-idf submodule update --init \ + components/bt/controller/lib_esp32 \ + components/bt/controller/lib_esp32c3_family + else + git -C esp-idf submodule update --init \ + components/bt/controller/lib + fi + ./esp-idf/install.sh +} + +function ci_esp32_idf402_setup { + ci_esp32_setup_helper v4.0.2 +} + +function ci_esp32_idf44_setup { + ci_esp32_setup_helper v4.4 +} + +function ci_esp32_build { + source esp-idf/export.sh + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/esp32 submodules + make ${MAKEOPTS} -C ports/esp32 \ + USER_C_MODULES=../../../examples/usercmodule/micropython.cmake \ + FROZEN_MANIFEST=$(pwd)/ports/esp32/boards/manifest_test.py + if [ -d $IDF_PATH/components/esp32c3 ]; then + make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_C3 + fi + if [ -d $IDF_PATH/components/esp32s2 ]; then + make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_S2 + fi + if [ -d $IDF_PATH/components/esp32s3 ]; then + make ${MAKEOPTS} -C ports/esp32 BOARD=GENERIC_S3 + fi + + # Test building native .mpy with xtensawin architecture. + ci_native_mpy_modules_build xtensawin +} + +######################################################################################## +# ports/esp8266 + +function ci_esp8266_setup { + sudo pip install pyserial esptool==3.3.1 + wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz + zcat xtensa-lx106-elf-standalone.tar.gz | tar x + # Remove this esptool.py so pip version is used instead + rm xtensa-lx106-elf/bin/esptool.py +} + +function ci_esp8266_path { + echo $(pwd)/xtensa-lx106-elf/bin +} + +function ci_esp8266_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/esp8266 submodules + make ${MAKEOPTS} -C ports/esp8266 + make ${MAKEOPTS} -C ports/esp8266 BOARD=GENERIC_512K + make ${MAKEOPTS} -C ports/esp8266 BOARD=GENERIC_1M +} + +######################################################################################## +# ports/javascript + +function ci_javascript_setup { + git clone https://github.com/emscripten-core/emsdk.git + (cd emsdk && ./emsdk install latest && ./emsdk activate latest) +} + +function ci_javascript_build { + source emsdk/emsdk_env.sh + make ${MAKEOPTS} -C ports/javascript +} + +function ci_javascript_run_tests { + # This port is very slow at running, so only run a few of the tests. + (cd tests && MICROPY_MICROPYTHON=../ports/javascript/node_run.sh ./run-tests.py -j1 basics/builtin_*.py) +} + +######################################################################################## +# ports/mimxrt + +function ci_mimxrt_setup { + ci_gcc_arm_setup +} + +function ci_mimxrt_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/mimxrt submodules + make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1020_EVK + make ${MAKEOPTS} -C ports/mimxrt BOARD=TEENSY40 +} + +######################################################################################## +# ports/nrf + +function ci_nrf_setup { + ci_gcc_arm_setup +} + +function ci_nrf_build { + ports/nrf/drivers/bluetooth/download_ble_stack.sh s140_nrf52_6_1_1 + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/nrf submodules + make ${MAKEOPTS} -C ports/nrf BOARD=pca10040 + make ${MAKEOPTS} -C ports/nrf BOARD=microbit + make ${MAKEOPTS} -C ports/nrf BOARD=pca10056 SD=s140 + make ${MAKEOPTS} -C ports/nrf BOARD=pca10090 +} + +######################################################################################## +# ports/powerpc + +function ci_powerpc_setup { + sudo apt-get update + sudo apt-get install gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross +} + +function ci_powerpc_build { + make ${MAKEOPTS} -C ports/powerpc UART=potato + make ${MAKEOPTS} -C ports/powerpc UART=lpc_serial +} + +######################################################################################## +# ports/qemu-arm + +function ci_qemu_arm_setup { + ci_gcc_arm_setup + sudo apt-get update + sudo apt-get install qemu-system + qemu-system-arm --version +} + +function ci_qemu_arm_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/qemu-arm CFLAGS_EXTRA=-DMP_ENDIANNESS_BIG=1 + make ${MAKEOPTS} -C ports/qemu-arm clean + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test clean + make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test BOARD=sabrelite test +} + +######################################################################################## +# ports/renesas-ra + +function ci_renesas_ra_setup { + ci_gcc_arm_setup +} + +function ci_renesas_ra_board_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/renesas-ra submodules + make ${MAKEOPTS} -C ports/renesas-ra BOARD=RA4M1_CLICKER + make ${MAKEOPTS} -C ports/renesas-ra BOARD=RA6M2_EK +} + +######################################################################################## +# ports/rp2 + +function ci_rp2_setup { + ci_gcc_arm_setup +} + +function ci_rp2_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/rp2 submodules + make ${MAKEOPTS} -C ports/rp2 + make ${MAKEOPTS} -C ports/rp2 clean + make ${MAKEOPTS} -C ports/rp2 USER_C_MODULES=../../examples/usercmodule/micropython.cmake + make ${MAKEOPTS} -C ports/rp2 BOARD=W5100S_EVB_PICO submodules + make ${MAKEOPTS} -C ports/rp2 BOARD=W5100S_EVB_PICO +} + +######################################################################################## +# ports/samd + +function ci_samd_setup { + ci_gcc_arm_setup +} + +function ci_samd_build { + make ${MAKEOPTS} -C ports/samd submodules + make ${MAKEOPTS} -C ports/samd +} + +######################################################################################## +# ports/stm32 + +function ci_stm32_setup { + ci_gcc_arm_setup + pip3 install pyelftools + pip3 install pyhy +} + +function ci_stm32_pyb_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/stm32 submodules + git submodule update --init lib/btstack + git submodule update --init lib/mynewt-nimble + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_NETWORK_WIZNET5K=5200 MICROPY_PY_CC3K=1 USER_C_MODULES=../../examples/usercmodule + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2 + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1 + make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBV10 CFLAGS_EXTRA='-DMBOOT_FSLOAD=1 -DMBOOT_VFS_LFS2=1' + make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6 + make ${MAKEOPTS} -C ports/stm32/mboot BOARD=STM32F769DISC CFLAGS_EXTRA='-DMBOOT_ADDRESS_SPACE_64BIT=1 -DMBOOT_SDCARD_ADDR=0x100000000ULL -DMBOOT_SDCARD_BYTE_SIZE=0x400000000ULL -DMBOOT_FSLOAD=1 -DMBOOT_VFS_FAT=1' + + # Test building native .mpy with armv7emsp architecture. + git submodule update --init lib/berkeley-db-1.xx + ci_native_mpy_modules_build armv7emsp +} + +function ci_stm32_nucleo_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/stm32 submodules + git submodule update --init lib/mynewt-nimble + + # Test building various MCU families, some with additional options. + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI COPT=-O2 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L073RZ + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L476RG DEBUG=1 + + # Test building a board with mboot packing enabled (encryption, signing, compression). + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WB55 USE_MBOOT=1 MBOOT_ENABLE_PACKING=1 + make ${MAKEOPTS} -C ports/stm32/mboot BOARD=NUCLEO_WB55 USE_MBOOT=1 MBOOT_ENABLE_PACKING=1 + # Test mboot_pack_dfu.py created a valid file, and that its unpack-dfu command works. + BOARD_WB55=ports/stm32/boards/NUCLEO_WB55 + BUILD_WB55=ports/stm32/build-NUCLEO_WB55 + python3 ports/stm32/mboot/mboot_pack_dfu.py -k $BOARD_WB55/mboot_keys.h unpack-dfu $BUILD_WB55/firmware.pack.dfu $BUILD_WB55/firmware.unpack.dfu + diff $BUILD_WB55/firmware.unpack.dfu $BUILD_WB55/firmware.dfu + # Test unpack-dfu command works without a secret key + tail -n +2 $BOARD_WB55/mboot_keys.h > $BOARD_WB55/mboot_keys_no_sk.h + python3 ports/stm32/mboot/mboot_pack_dfu.py -k $BOARD_WB55/mboot_keys_no_sk.h unpack-dfu $BUILD_WB55/firmware.pack.dfu $BUILD_WB55/firmware.unpack_no_sk.dfu + diff $BUILD_WB55/firmware.unpack.dfu $BUILD_WB55/firmware.unpack_no_sk.dfu +} + +######################################################################################## +# ports/teensy + +function ci_teensy_setup { + ci_gcc_arm_setup +} + +function ci_teensy_build { + make ${MAKEOPTS} -C ports/teensy +} + +######################################################################################## +# ports/unix + +CI_UNIX_OPTS_SYS_SETTRACE=( + MICROPY_PY_BTREE=0 + MICROPY_PY_FFI=0 + MICROPY_PY_USSL=0 + CFLAGS_EXTRA="-DMICROPY_PY_SYS_SETTRACE=1" +) + +CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS=( + MICROPY_PY_BTREE=0 + MICROPY_PY_FFI=0 + MICROPY_PY_USSL=0 + CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1 -DMICROPY_PY_SYS_SETTRACE=1" +) + +CI_UNIX_OPTS_QEMU_MIPS=( + CROSS_COMPILE=mips-linux-gnu- + VARIANT=coverage + MICROPY_STANDALONE=1 + LDFLAGS_EXTRA="-static" +) + +CI_UNIX_OPTS_QEMU_ARM=( + CROSS_COMPILE=arm-linux-gnueabi- + VARIANT=coverage + MICROPY_STANDALONE=1 +) + +function ci_unix_build_helper { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/unix "$@" submodules + make ${MAKEOPTS} -C ports/unix "$@" deplibs + make ${MAKEOPTS} -C ports/unix "$@" +} + +function ci_unix_build_ffi_lib_helper { + $1 $2 -shared -o tests/unix/ffi_lib.so tests/unix/ffi_lib.c +} + +function ci_unix_run_tests_helper { + make -C ports/unix "$@" test +} + +function ci_unix_run_tests_full_helper { + variant=$1 + shift + if [ $variant = standard ]; then + micropython=micropython + else + micropython=micropython-$variant + fi + make -C ports/unix VARIANT=$variant "$@" test_full + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/$micropython ./run-multitests.py multi_net/*.py) + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/$micropython ./run-perfbench.py 1000 1000) +} + +function ci_native_mpy_modules_build { + if [ "$1" = "" ]; then + arch=x64 + else + arch=$1 + fi + make -C examples/natmod/features1 ARCH=$arch + make -C examples/natmod/features2 ARCH=$arch + make -C examples/natmod/features3 ARCH=$arch + make -C examples/natmod/btree ARCH=$arch + make -C examples/natmod/framebuf ARCH=$arch + make -C examples/natmod/uheapq ARCH=$arch + make -C examples/natmod/urandom ARCH=$arch + make -C examples/natmod/ure ARCH=$arch + make -C examples/natmod/uzlib ARCH=$arch +} + +function ci_native_mpy_modules_32bit_build { + ci_native_mpy_modules_build x86 +} + +function ci_unix_minimal_build { + make ${MAKEOPTS} -C ports/unix VARIANT=minimal +} + +function ci_unix_minimal_run_tests { + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/micropython-minimal ./run-tests.py -e exception_chain -e self_type_check -e subclass_native_init -d basics) +} + +function ci_unix_standard_build { + ci_unix_build_helper VARIANT=standard + ci_unix_build_ffi_lib_helper gcc +} + +function ci_unix_standard_run_tests { + ci_unix_run_tests_full_helper standard +} + +function ci_unix_dev_build { + ci_unix_build_helper VARIANT=dev +} + +function ci_unix_dev_run_tests { + ci_unix_run_tests_helper VARIANT=dev +} + +function ci_unix_coverage_setup { + sudo pip3 install setuptools + sudo pip3 install pyelftools + gcc --version + python3 --version +} + +function ci_unix_coverage_build { + ci_unix_build_helper VARIANT=coverage + ci_unix_build_ffi_lib_helper gcc +} + +function ci_unix_coverage_run_tests { + ci_unix_run_tests_full_helper coverage +} + +function ci_unix_coverage_run_mpy_merge_tests { + mptop=$(pwd) + outdir=$(mktemp -d) + allmpy=() + + # Compile a selection of tests to .mpy and execute them, collecting the output. + # None of the tests should SKIP. + for inpy in $mptop/tests/basics/[acdel]*.py; do + test=$(basename $inpy .py) + echo $test + outmpy=$outdir/$test.mpy + $mptop/mpy-cross/mpy-cross -o $outmpy $inpy + (cd $outdir && $mptop/ports/unix/micropython-coverage -m $test >> out-individual) + allmpy+=($outmpy) + done + + # Merge all the tests into one .mpy file, and then execute it. + python3 $mptop/tools/mpy-tool.py --merge -o $outdir/merged.mpy ${allmpy[@]} + (cd $outdir && $mptop/ports/unix/micropython-coverage -m merged > out-merged) + + # Make sure the outputs match. + diff $outdir/out-individual $outdir/out-merged && /bin/rm -rf $outdir +} + +function ci_unix_coverage_run_native_mpy_tests { + MICROPYPATH=examples/natmod/features2 ./ports/unix/micropython-coverage -m features2 + (cd tests && ./run-natmodtests.py "$@" extmod/{btree*,framebuf*,uheapq*,urandom*,ure*,uzlib*}.py) +} + +function ci_unix_32bit_setup { + sudo dpkg --add-architecture i386 + sudo apt-get update + sudo apt-get install gcc-multilib g++-multilib libffi-dev:i386 + sudo pip3 install setuptools + sudo pip3 install pyelftools + gcc --version + python2 --version + python3 --version +} + +function ci_unix_coverage_32bit_build { + ci_unix_build_helper VARIANT=coverage MICROPY_FORCE_32BIT=1 + ci_unix_build_ffi_lib_helper gcc -m32 +} + +function ci_unix_coverage_32bit_run_tests { + ci_unix_run_tests_full_helper coverage MICROPY_FORCE_32BIT=1 +} + +function ci_unix_coverage_32bit_run_native_mpy_tests { + ci_unix_coverage_run_native_mpy_tests --arch x86 +} + +function ci_unix_nanbox_build { + # Use Python 2 to check that it can run the build scripts + ci_unix_build_helper PYTHON=python2 VARIANT=nanbox CFLAGS_EXTRA="-DMICROPY_PY_MATH_CONSTANTS=1" + ci_unix_build_ffi_lib_helper gcc -m32 +} + +function ci_unix_nanbox_run_tests { + ci_unix_run_tests_full_helper nanbox PYTHON=python2 +} + +function ci_unix_float_build { + ci_unix_build_helper VARIANT=standard CFLAGS_EXTRA="-DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT" + ci_unix_build_ffi_lib_helper gcc +} + +function ci_unix_float_run_tests { + # TODO get this working: ci_unix_run_tests_full_helper standard CFLAGS_EXTRA="-DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT" + ci_unix_run_tests_helper CFLAGS_EXTRA="-DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT" +} + +function ci_unix_clang_setup { + sudo apt-get install clang + clang --version +} + +function ci_unix_stackless_clang_build { + make ${MAKEOPTS} -C mpy-cross CC=clang + make ${MAKEOPTS} -C ports/unix submodules + make ${MAKEOPTS} -C ports/unix CC=clang CFLAGS_EXTRA="-DMICROPY_STACKLESS=1 -DMICROPY_STACKLESS_STRICT=1" +} + +function ci_unix_stackless_clang_run_tests { + ci_unix_run_tests_helper CC=clang +} + +function ci_unix_float_clang_build { + make ${MAKEOPTS} -C mpy-cross CC=clang + make ${MAKEOPTS} -C ports/unix submodules + make ${MAKEOPTS} -C ports/unix CC=clang CFLAGS_EXTRA="-DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT" +} + +function ci_unix_float_clang_run_tests { + ci_unix_run_tests_helper CC=clang +} + +function ci_unix_settrace_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SYS_SETTRACE[@]}" +} + +function ci_unix_settrace_run_tests { + ci_unix_run_tests_full_helper standard "${CI_UNIX_OPTS_SYS_SETTRACE[@]}" +} + +function ci_unix_settrace_stackless_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS[@]}" +} + +function ci_unix_settrace_stackless_run_tests { + ci_unix_run_tests_full_helper standard "${CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS[@]}" +} + +function ci_unix_macos_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/unix submodules + #make ${MAKEOPTS} -C ports/unix deplibs + make ${MAKEOPTS} -C ports/unix + # check for additional compiler errors/warnings + make ${MAKEOPTS} -C ports/unix VARIANT=dev submodules + make ${MAKEOPTS} -C ports/unix VARIANT=dev + make ${MAKEOPTS} -C ports/unix VARIANT=coverage submodules + make ${MAKEOPTS} -C ports/unix VARIANT=coverage +} + +function ci_unix_macos_run_tests { + # Issues with macOS tests: + # - import_pkg7 has a problem with relative imports + # - urandom_basic has a problem with getrandbits(0) + (cd tests && ./run-tests.py --exclude 'import_pkg7.py' --exclude 'urandom_basic.py') +} + +function ci_unix_qemu_mips_setup { + sudo apt-get update + sudo apt-get install gcc-mips-linux-gnu g++-mips-linux-gnu + sudo apt-get install qemu-user + qemu-mips --version +} + +function ci_unix_qemu_mips_build { + # qemu-mips on GitHub Actions will seg-fault if not linked statically + ci_unix_build_helper "${CI_UNIX_OPTS_QEMU_MIPS[@]}" +} + +function ci_unix_qemu_mips_run_tests { + # Issues with MIPS tests: + # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) + # - ffi tests do not work + file ./ports/unix/micropython-coverage + (cd tests && MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py' --exclude 'ffi_(callback|float|float2).py') +} + +function ci_unix_qemu_arm_setup { + sudo apt-get update + sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi + sudo apt-get install qemu-user + qemu-arm --version +} + +function ci_unix_qemu_arm_build { + ci_unix_build_helper "${CI_UNIX_OPTS_QEMU_ARM[@]}" + ci_unix_build_ffi_lib_helper arm-linux-gnueabi-gcc +} + +function ci_unix_qemu_arm_run_tests { + # Issues with ARM tests: + # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) + export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi + file ./ports/unix/micropython-coverage + (cd tests && MICROPY_MICROPYTHON=../ports/unix/micropython-coverage ./run-tests.py --exclude 'vfs_posix.py') +} + +######################################################################################## +# ports/windows + +function ci_windows_setup { + sudo apt-get install gcc-mingw-w64 +} + +function ci_windows_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32- +} + +######################################################################################## +# ports/zephyr + +ZEPHYR_DOCKER_VERSION=v0.21.0 +ZEPHYR_SDK_VERSION=0.13.2 +ZEPHYR_VERSION=v3.0.0 + +function ci_zephyr_setup { + docker pull zephyrprojectrtos/ci:${ZEPHYR_DOCKER_VERSION} + docker run --name zephyr-ci -d -it \ + -v "$(pwd)":/micropython \ + -e ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-${ZEPHYR_SDK_VERSION} \ + -e ZEPHYR_TOOLCHAIN_VARIANT=zephyr \ + -e ZEPHYR_BASE=/zephyrproject/zephyr \ + -w /micropython/ports/zephyr \ + zephyrprojectrtos/ci:${ZEPHYR_DOCKER_VERSION} + docker ps -a +} + +function ci_zephyr_install { + docker exec zephyr-ci west init --mr ${ZEPHYR_VERSION} /zephyrproject + docker exec -w /zephyrproject zephyr-ci west update + docker exec -w /zephyrproject zephyr-ci west zephyr-export +} + +function ci_zephyr_build { + docker exec zephyr-ci west build -p auto -b qemu_x86 -- -DCONF_FILE=prj_minimal.conf + docker exec zephyr-ci west build -p auto -b qemu_x86 + docker exec zephyr-ci west build -p auto -b frdm_k64f + docker exec zephyr-ci west build -p auto -b mimxrt1050_evk + docker exec zephyr-ci west build -p auto -b nucleo_wb55rg # for bluetooth +} diff --git a/tools/ci_fetch_deps.py b/tools/ci_fetch_deps.py index 15ef6a51cdc5a..caaea8cea88e1 100644 --- a/tools/ci_fetch_deps.py +++ b/tools/ci_fetch_deps.py @@ -79,6 +79,10 @@ def main(): submodules = ["extmod/ulab", "lib/", "tools/"] elif TARGET == "tests": submodules = ["extmod/ulab", "lib/", "tools/"] + submodules_tags = [ + "frozen/Adafruit_CircuitPython_asyncio", + "frozen/Adafruit_CircuitPython_Ticks", + ] elif TARGET == "docs": # used in .readthedocs.yml to generate RTD submodules = ["extmod/ulab"] diff --git a/tools/merge_micropython.py b/tools/merge_micropython.py index ce3736ddb75be..a6d3efcc0dac0 100644 --- a/tools/merge_micropython.py +++ b/tools/merge_micropython.py @@ -1,6 +1,6 @@ """ This is a helper script for merging in new versions of MicroPython. You *must* -evaluate it's correctness and adapt it for each MP version. This is committed +evaluate its correctness and adapt it for each MP version. This is committed in the repo more for reference than "fire and forget" use. """ @@ -11,22 +11,24 @@ out_buf = StringIO() ports_to_delete = [ + "bare-arm", + "cc3200", + "embed", + "esp32", + "esp8266", + "javascript", "mimxrt", + "minimal", + "pic16bit", "powerpc", + "qemu-arm", + "renesas-ra", + "rp2", "samd", - "javascript", "stm32", - "esp32", - "cc3200", "teensy", "windows", "zephyr", - "minimal", - "esp8266", - "pic16bit", - "qemu-arm", - "bare-arm", - "rp2", ] for p in ports_to_delete: try: diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 02ea656c99bdc..3a59ac659029f 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -1,35 +1,81 @@ #!/usr/bin/env python3 - -# SPDX-FileCopyrightText: Copyright (c) 2016-2019 Damien P. George -# SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) # -# SPDX-License-Identifier: MIT +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2016-2019 Damien P. George +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. # Python 2/3 compatibility code from __future__ import print_function import platform if platform.python_version_tuple()[0] == "2": - str_cons = lambda val, enc=None: val + from binascii import hexlify as hexlify_py2 + + str_cons = lambda val, enc=None: str(val) bytes_cons = lambda val, enc=None: bytearray(val) is_str_type = lambda o: type(o) is str is_bytes_type = lambda o: type(o) is bytearray is_int_type = lambda o: type(o) is int or type(o) is long + + def hexlify_to_str(b): + x = hexlify_py2(b) + return ":".join(x[i : i + 2] for i in range(0, len(x), 2)) + else: + from binascii import hexlify + str_cons = str bytes_cons = bytes is_str_type = lambda o: type(o) is str is_bytes_type = lambda o: type(o) is bytes is_int_type = lambda o: type(o) is int + + def hexlify_to_str(b): + return str(hexlify(b, ":"), "ascii") + + # end compatibility code import sys import struct -from collections import namedtuple sys.path.append(sys.path[0] + "/../py") import makeqstrdata as qstrutil +# Threshold of str length below which it will be turned into a qstr when freezing. +# This helps to reduce frozen code size because qstrs are more efficient to encode +# as objects than full mp_obj_str_t instances. +PERSISTENT_STR_INTERN_THRESHOLD = 25 + + +class MPYReadError(Exception): + def __init__(self, filename, msg): + self.filename = filename + self.msg = msg + + def __str__(self): + return "%s: %s" % (self.filename, self.msg) + class FreezeError(Exception): def __init__(self, rawcode, msg): @@ -41,7 +87,7 @@ def __str__(self): class Config: - MPY_VERSION = 5 + MPY_VERSION = 6 MICROPY_LONGINT_IMPL_NONE = 0 MICROPY_LONGINT_IMPL_LONGLONG = 1 MICROPY_LONGINT_IMPL_MPZ = 2 @@ -50,33 +96,6 @@ class Config: config = Config() -class QStrType: - def __init__(self, str): - self.str = str - self.qstr_esc = qstrutil.qstr_escape(self.str) - self.qstr_id = "MP_QSTR_" + self.qstr_esc - - -# Initialise global list of qstrs with static qstrs -global_qstrs = [None] # MP_QSTRnull should never be referenced -for n in qstrutil.static_qstr_list: - global_qstrs.append(QStrType(n)) - - -class QStrWindow: - def __init__(self, size): - self.window = [] - self.size = size - - def push(self, val): - self.window = [val] + self.window[: self.size - 1] - - def access(self, idx): - val = self.window[idx] - self.window = [val] + self.window[:idx] + self.window[idx + 1 :] - return val - - MP_CODE_BYTECODE = 2 MP_CODE_NATIVE_PY = 3 MP_CODE_NATIVE_VIPER = 4 @@ -94,6 +113,23 @@ def access(self, idx): MP_NATIVE_ARCH_XTENSA = 9 MP_NATIVE_ARCH_XTENSAWIN = 10 +MP_PERSISTENT_OBJ_FUN_TABLE = 0 +MP_PERSISTENT_OBJ_NONE = 1 +MP_PERSISTENT_OBJ_FALSE = 2 +MP_PERSISTENT_OBJ_TRUE = 3 +MP_PERSISTENT_OBJ_ELLIPSIS = 4 +MP_PERSISTENT_OBJ_STR = 5 +MP_PERSISTENT_OBJ_BYTES = 6 +MP_PERSISTENT_OBJ_INT = 7 +MP_PERSISTENT_OBJ_FLOAT = 8 +MP_PERSISTENT_OBJ_COMPLEX = 9 +MP_PERSISTENT_OBJ_TUPLE = 10 + +# Circuitpython: this does not match upstream because we added MP_SCOPE_FLAG_ASYNC +MP_SCOPE_FLAG_VIPERRELOC = 0x10 +MP_SCOPE_FLAG_VIPERRODATA = 0x20 +MP_SCOPE_FLAG_VIPERBSS = 0x40 + MP_BC_MASK_EXTRA_BYTE = 0x9E MP_BC_FORMAT_BYTE = 0 @@ -101,32 +137,278 @@ def access(self, idx): MP_BC_FORMAT_VAR_UINT = 2 MP_BC_FORMAT_OFFSET = 3 -# extra byte if caching enabled: -MP_BC_LOAD_NAME = 0x11 -MP_BC_LOAD_GLOBAL = 0x12 -MP_BC_LOAD_ATTR = 0x13 -MP_BC_STORE_ATTR = 0x18 - +mp_unary_op_method_name = ( + "__pos__", + "__neg__", + "__invert__", + "", +) + +mp_binary_op_method_name = ( + "__lt__", + "__gt__", + "__eq__", + "__le__", + "__ge__", + "__ne__", + "", + "", + "", + "__ior__", + "__ixor__", + "__iand__", + "__ilshift__", + "__irshift__", + "__iadd__", + "__isub__", + "__imul__", + "__imatmul__", + "__ifloordiv__", + "__itruediv__", + "__imod__", + "__ipow__", + "__or__", + "__xor__", + "__and__", + "__lshift__", + "__rshift__", + "__add__", + "__sub__", + "__mul__", + "__matmul__", + "__floordiv__", + "__truediv__", + "__mod__", + "__pow__", +) + + +class Opcode: + # fmt: off + # Load, Store, Delete, Import, Make, Build, Unpack, Call, Jump, Exception, For, sTack, Return, Yield, Op + MP_BC_BASE_RESERVED = (0x00) # ---------------- + MP_BC_BASE_QSTR_O = (0x10) # LLLLLLSSSDDII--- + MP_BC_BASE_VINT_E = (0x20) # MMLLLLSSDDBBBBBB + MP_BC_BASE_VINT_O = (0x30) # UUMMCCCC-------- + MP_BC_BASE_JUMP_E = (0x40) # J-JJJJJEEEEF---- + MP_BC_BASE_BYTE_O = (0x50) # LLLLSSDTTTTTEEFF + MP_BC_BASE_BYTE_E = (0x60) # --BREEEYYI------ + MP_BC_LOAD_CONST_SMALL_INT_MULTI = (0x70) # LLLLLLLLLLLLLLLL + # = (0x80) # LLLLLLLLLLLLLLLL + # = (0x90) # LLLLLLLLLLLLLLLL + # = (0xa0) # LLLLLLLLLLLLLLLL + MP_BC_LOAD_FAST_MULTI = (0xb0) # LLLLLLLLLLLLLLLL + MP_BC_STORE_FAST_MULTI = (0xc0) # SSSSSSSSSSSSSSSS + MP_BC_UNARY_OP_MULTI = (0xd0) # OOOOOOO + MP_BC_BINARY_OP_MULTI = (0xd7) # OOOOOOOOO + # = (0xe0) # OOOOOOOOOOOOOOOO + # = (0xf0) # OOOOOOOOOO------ + + MP_BC_LOAD_CONST_SMALL_INT_MULTI_NUM = 64 + MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS = 16 + MP_BC_LOAD_FAST_MULTI_NUM = 16 + MP_BC_STORE_FAST_MULTI_NUM = 16 + MP_BC_UNARY_OP_MULTI_NUM = 4 # MP_UNARY_OP_NUM_BYTECODE + MP_BC_BINARY_OP_MULTI_NUM = 35 # MP_BINARY_OP_NUM_BYTECODE + + MP_BC_LOAD_CONST_FALSE = (MP_BC_BASE_BYTE_O + 0x00) + MP_BC_LOAD_CONST_NONE = (MP_BC_BASE_BYTE_O + 0x01) + MP_BC_LOAD_CONST_TRUE = (MP_BC_BASE_BYTE_O + 0x02) + MP_BC_LOAD_CONST_SMALL_INT = (MP_BC_BASE_VINT_E + 0x02) # signed var-int + MP_BC_LOAD_CONST_STRING = (MP_BC_BASE_QSTR_O + 0x00) # qstr + MP_BC_LOAD_CONST_OBJ = (MP_BC_BASE_VINT_E + 0x03) # ptr + MP_BC_LOAD_NULL = (MP_BC_BASE_BYTE_O + 0x03) + + MP_BC_LOAD_FAST_N = (MP_BC_BASE_VINT_E + 0x04) # uint + MP_BC_LOAD_DEREF = (MP_BC_BASE_VINT_E + 0x05) # uint + MP_BC_LOAD_NAME = (MP_BC_BASE_QSTR_O + 0x01) # qstr + MP_BC_LOAD_GLOBAL = (MP_BC_BASE_QSTR_O + 0x02) # qstr + MP_BC_LOAD_ATTR = (MP_BC_BASE_QSTR_O + 0x03) # qstr + MP_BC_LOAD_METHOD = (MP_BC_BASE_QSTR_O + 0x04) # qstr + MP_BC_LOAD_SUPER_METHOD = (MP_BC_BASE_QSTR_O + 0x05) # qstr + MP_BC_LOAD_BUILD_CLASS = (MP_BC_BASE_BYTE_O + 0x04) + MP_BC_LOAD_SUBSCR = (MP_BC_BASE_BYTE_O + 0x05) + + MP_BC_STORE_FAST_N = (MP_BC_BASE_VINT_E + 0x06) # uint + MP_BC_STORE_DEREF = (MP_BC_BASE_VINT_E + 0x07) # uint + MP_BC_STORE_NAME = (MP_BC_BASE_QSTR_O + 0x06) # qstr + MP_BC_STORE_GLOBAL = (MP_BC_BASE_QSTR_O + 0x07) # qstr + MP_BC_STORE_ATTR = (MP_BC_BASE_QSTR_O + 0x08) # qstr + MP_BC_STORE_SUBSCR = (MP_BC_BASE_BYTE_O + 0x06) + + MP_BC_DELETE_FAST = (MP_BC_BASE_VINT_E + 0x08) # uint + MP_BC_DELETE_DEREF = (MP_BC_BASE_VINT_E + 0x09) # uint + MP_BC_DELETE_NAME = (MP_BC_BASE_QSTR_O + 0x09) # qstr + MP_BC_DELETE_GLOBAL = (MP_BC_BASE_QSTR_O + 0x0a) # qstr + + MP_BC_DUP_TOP = (MP_BC_BASE_BYTE_O + 0x07) + MP_BC_DUP_TOP_TWO = (MP_BC_BASE_BYTE_O + 0x08) + MP_BC_POP_TOP = (MP_BC_BASE_BYTE_O + 0x09) + MP_BC_ROT_TWO = (MP_BC_BASE_BYTE_O + 0x0a) + MP_BC_ROT_THREE = (MP_BC_BASE_BYTE_O + 0x0b) + + MP_BC_UNWIND_JUMP = (MP_BC_BASE_JUMP_E + 0x00) # signed relative bytecode offset; then a byte + MP_BC_JUMP = (MP_BC_BASE_JUMP_E + 0x02) # signed relative bytecode offset + MP_BC_POP_JUMP_IF_TRUE = (MP_BC_BASE_JUMP_E + 0x03) # signed relative bytecode offset + MP_BC_POP_JUMP_IF_FALSE = (MP_BC_BASE_JUMP_E + 0x04) # signed relative bytecode offset + MP_BC_JUMP_IF_TRUE_OR_POP = (MP_BC_BASE_JUMP_E + 0x05) # unsigned relative bytecode offset + MP_BC_JUMP_IF_FALSE_OR_POP = (MP_BC_BASE_JUMP_E + 0x06) # unsigned relative bytecode offset + MP_BC_SETUP_WITH = (MP_BC_BASE_JUMP_E + 0x07) # unsigned relative bytecode offset + MP_BC_SETUP_EXCEPT = (MP_BC_BASE_JUMP_E + 0x08) # unsigned relative bytecode offset + MP_BC_SETUP_FINALLY = (MP_BC_BASE_JUMP_E + 0x09) # unsigned relative bytecode offset + MP_BC_POP_EXCEPT_JUMP = (MP_BC_BASE_JUMP_E + 0x0a) # unsigned relative bytecode offset + MP_BC_FOR_ITER = (MP_BC_BASE_JUMP_E + 0x0b) # unsigned relative bytecode offset + MP_BC_WITH_CLEANUP = (MP_BC_BASE_BYTE_O + 0x0c) + MP_BC_END_FINALLY = (MP_BC_BASE_BYTE_O + 0x0d) + MP_BC_GET_ITER = (MP_BC_BASE_BYTE_O + 0x0e) + MP_BC_GET_ITER_STACK = (MP_BC_BASE_BYTE_O + 0x0f) + + MP_BC_BUILD_TUPLE = (MP_BC_BASE_VINT_E + 0x0a) # uint + MP_BC_BUILD_LIST = (MP_BC_BASE_VINT_E + 0x0b) # uint + MP_BC_BUILD_MAP = (MP_BC_BASE_VINT_E + 0x0c) # uint + MP_BC_STORE_MAP = (MP_BC_BASE_BYTE_E + 0x02) + MP_BC_BUILD_SET = (MP_BC_BASE_VINT_E + 0x0d) # uint + MP_BC_BUILD_SLICE = (MP_BC_BASE_VINT_E + 0x0e) # uint + MP_BC_STORE_COMP = (MP_BC_BASE_VINT_E + 0x0f) # uint + MP_BC_UNPACK_SEQUENCE = (MP_BC_BASE_VINT_O + 0x00) # uint + MP_BC_UNPACK_EX = (MP_BC_BASE_VINT_O + 0x01) # uint + + MP_BC_RETURN_VALUE = (MP_BC_BASE_BYTE_E + 0x03) + MP_BC_RAISE_LAST = (MP_BC_BASE_BYTE_E + 0x04) + MP_BC_RAISE_OBJ = (MP_BC_BASE_BYTE_E + 0x05) + MP_BC_RAISE_FROM = (MP_BC_BASE_BYTE_E + 0x06) + MP_BC_YIELD_VALUE = (MP_BC_BASE_BYTE_E + 0x07) + MP_BC_YIELD_FROM = (MP_BC_BASE_BYTE_E + 0x08) + + MP_BC_MAKE_FUNCTION = (MP_BC_BASE_VINT_O + 0x02) # uint + MP_BC_MAKE_FUNCTION_DEFARGS = (MP_BC_BASE_VINT_O + 0x03) # uint + MP_BC_MAKE_CLOSURE = (MP_BC_BASE_VINT_E + 0x00) # uint; extra byte + MP_BC_MAKE_CLOSURE_DEFARGS = (MP_BC_BASE_VINT_E + 0x01) # uint; extra byte + MP_BC_CALL_FUNCTION = (MP_BC_BASE_VINT_O + 0x04) # uint + MP_BC_CALL_FUNCTION_VAR_KW = (MP_BC_BASE_VINT_O + 0x05) # uint + MP_BC_CALL_METHOD = (MP_BC_BASE_VINT_O + 0x06) # uint + MP_BC_CALL_METHOD_VAR_KW = (MP_BC_BASE_VINT_O + 0x07) # uint + + MP_BC_IMPORT_NAME = (MP_BC_BASE_QSTR_O + 0x0b) # qstr + MP_BC_IMPORT_FROM = (MP_BC_BASE_QSTR_O + 0x0c) # qstr + MP_BC_IMPORT_STAR = (MP_BC_BASE_BYTE_E + 0x09) + # fmt: on + + # Create sets of related opcodes. + ALL_OFFSET_SIGNED = ( + MP_BC_UNWIND_JUMP, + MP_BC_JUMP, + MP_BC_POP_JUMP_IF_TRUE, + MP_BC_POP_JUMP_IF_FALSE, + ) -# this function mirrors that in py/bc.c -def mp_opcode_format(bytecode, ip, count_var_uint): + # Create a dict mapping opcode value to opcode name. + mapping = ["unknown" for _ in range(256)] + for op_name in list(locals()): + if op_name.startswith("MP_BC_"): + mapping[locals()[op_name]] = op_name[len("MP_BC_") :] + for i in range(MP_BC_LOAD_CONST_SMALL_INT_MULTI_NUM): + name = "LOAD_CONST_SMALL_INT %d" % (i - MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS) + mapping[MP_BC_LOAD_CONST_SMALL_INT_MULTI + i] = name + for i in range(MP_BC_LOAD_FAST_MULTI_NUM): + mapping[MP_BC_LOAD_FAST_MULTI + i] = "LOAD_FAST %d" % i + for i in range(MP_BC_STORE_FAST_MULTI_NUM): + mapping[MP_BC_STORE_FAST_MULTI + i] = "STORE_FAST %d" % i + for i in range(MP_BC_UNARY_OP_MULTI_NUM): + mapping[MP_BC_UNARY_OP_MULTI + i] = "UNARY_OP %d %s" % (i, mp_unary_op_method_name[i]) + for i in range(MP_BC_BINARY_OP_MULTI_NUM): + mapping[MP_BC_BINARY_OP_MULTI + i] = "BINARY_OP %d %s" % (i, mp_binary_op_method_name[i]) + + def __init__(self, offset, fmt, opcode_byte, arg, extra_arg): + self.offset = offset + self.fmt = fmt + self.opcode_byte = opcode_byte + self.arg = arg + self.extra_arg = extra_arg + + +# CIRCUITPY: we assume MICROPY_OBJ_REPR_C +def mp_small_int_fits(i): + return -0x4_000_000 <= i <= 0x3_FFF_FFF + + +def mp_encode_uint(val, signed=False): + encoded = bytearray([val & 0x7F]) + val >>= 7 + while val != 0 and val != -1: + encoded.insert(0, 0x80 | (val & 0x7F)) + val >>= 7 + if signed: + if val == -1 and encoded[0] & 0x40 == 0: + encoded.insert(0, 0xFF) + elif val == 0 and encoded[0] & 0x40 != 0: + encoded.insert(0, 0x80) + return encoded + + +def mp_opcode_decode(bytecode, ip): opcode = bytecode[ip] ip_start = ip f = (0x000003A4 >> (2 * ((opcode) >> 4))) & 3 - if f == MP_BC_FORMAT_QSTR: - ip += 3 - else: - extra_byte = (opcode & MP_BC_MASK_EXTRA_BYTE) == 0 + ip += 1 + arg = None + extra_arg = None + if f in (MP_BC_FORMAT_QSTR, MP_BC_FORMAT_VAR_UINT): + arg = bytecode[ip] & 0x7F + if opcode == Opcode.MP_BC_LOAD_CONST_SMALL_INT and arg & 0x40 != 0: + arg |= -1 << 7 + while bytecode[ip] & 0x80 != 0: + ip += 1 + arg = arg << 7 | bytecode[ip] & 0x7F ip += 1 - if f == MP_BC_FORMAT_VAR_UINT: - if count_var_uint: - while bytecode[ip] & 0x80 != 0: - ip += 1 - ip += 1 - elif f == MP_BC_FORMAT_OFFSET: + elif f == MP_BC_FORMAT_OFFSET: + if bytecode[ip] & 0x80 == 0: + arg = bytecode[ip] + ip += 1 + if opcode in Opcode.ALL_OFFSET_SIGNED: + arg -= 0x40 + else: + arg = bytecode[ip] & 0x7F | bytecode[ip + 1] << 7 ip += 2 - ip += extra_byte - return f, ip - ip_start + if opcode in Opcode.ALL_OFFSET_SIGNED: + arg -= 0x4000 + if opcode & MP_BC_MASK_EXTRA_BYTE == 0: + extra_arg = bytecode[ip] + ip += 1 + return f, ip - ip_start, arg, extra_arg + + +def mp_opcode_encode(opcode): + overflow = False + encoded = bytearray([opcode.opcode_byte]) + if opcode.fmt in (MP_BC_FORMAT_QSTR, MP_BC_FORMAT_VAR_UINT): + signed = opcode.opcode_byte == Opcode.MP_BC_LOAD_CONST_SMALL_INT + encoded.extend(mp_encode_uint(opcode.arg, signed)) + elif opcode.fmt == MP_BC_FORMAT_OFFSET: + is_signed = opcode.opcode_byte in Opcode.ALL_OFFSET_SIGNED + + # The -2 accounts for this jump opcode taking 2 bytes (at least). + bytecode_offset = opcode.target.offset - opcode.offset - 2 + + # Check if the bytecode_offset is small enough to use a 1-byte encoding. + if (is_signed and -64 <= bytecode_offset <= 63) or ( + not is_signed and bytecode_offset <= 127 + ): + # Use a 1-byte jump offset. + if is_signed: + bytecode_offset += 0x40 + overflow = not (0 <= bytecode_offset <= 0x7F) + encoded.append(bytecode_offset & 0x7F) + else: + bytecode_offset -= 1 + if is_signed: + bytecode_offset += 0x4000 + overflow = not (0 <= bytecode_offset <= 0x7FFF) + encoded.append(0x80 | (bytecode_offset & 0x7F)) + encoded.append((bytecode_offset >> 7) & 0xFF) + if opcode.extra_arg is not None: + encoded.append(opcode.extra_arg) + return overflow, encoded def read_prelude_sig(read_byte): @@ -168,6 +450,21 @@ def read_prelude_size(read_byte): return I, C +# See py/bc.h:MP_BC_PRELUDE_SIZE_ENCODE macro. +def encode_prelude_size(I, C): + # Encode bit-wise as: xIIIIIIC + encoded = bytearray() + while True: + z = (I & 0x3F) << 1 | (C & 1) + C >>= 1 + I >>= 6 + if C | I: + z |= 0x80 + encoded.append(z) + if not C | I: + return encoded + + def extract_prelude(bytecode, ip): def local_read_byte(): b = bytecode[ip_ref[0]] @@ -175,6 +472,8 @@ def local_read_byte(): return b ip_ref = [ip] # to close over ip in Python 2 and 3 + + # Read prelude signature. ( n_state, n_exc_stack, @@ -183,18 +482,358 @@ def local_read_byte(): n_kwonly_args, n_def_pos_args, ) = read_prelude_sig(local_read_byte) + + offset_prelude_size = ip_ref[0] + + # Read prelude size. n_info, n_cell = read_prelude_size(local_read_byte) - ip = ip_ref[0] - ip2 = ip - ip = ip2 + n_info + n_cell - # ip now points to first opcode - # ip2 points to simple_name qstr - return ip, ip2, (n_state, n_exc_stack, scope_flags, n_pos_args, n_kwonly_args, n_def_pos_args) + offset_source_info = ip_ref[0] + + # Extract simple_name and argument qstrs (var uints). + args = [] + for arg_num in range(1 + n_pos_args + n_kwonly_args): + value = 0 + while True: + b = local_read_byte() + value = (value << 7) | (b & 0x7F) + if b & 0x80 == 0: + break + args.append(value) + + offset_line_info = ip_ref[0] + offset_closure_info = offset_source_info + n_info + offset_opcodes = offset_source_info + n_info + n_cell + + return ( + offset_prelude_size, + offset_source_info, + offset_line_info, + offset_closure_info, + offset_opcodes, + (n_state, n_exc_stack, scope_flags, n_pos_args, n_kwonly_args, n_def_pos_args), + (n_info, n_cell), + args, + ) + + +class QStrType: + def __init__(self, str): + self.str = str + self.qstr_esc = qstrutil.qstr_escape(self.str) + self.qstr_id = "MP_QSTR_" + self.qstr_esc + + +class GlobalQStrList: + def __init__(self): + # Initialise global list of qstrs with static qstrs + self.qstrs = [None] # MP_QSTRnull should never be referenced + for n in qstrutil.static_qstr_list: + self.qstrs.append(QStrType(n)) + + def add(self, s): + q = QStrType(s) + self.qstrs.append(q) + return q + + def get_by_index(self, i): + return self.qstrs[i] + + def find_by_str(self, s): + for q in self.qstrs: + if q is not None and q.str == s: + return q + return None class MPFunTable: - pass + def __repr__(self): + return "mp_fun_table" + + +class CompiledModule: + def __init__( + self, + mpy_source_file, + mpy_segments, + header, + qstr_table, + obj_table, + raw_code, + qstr_table_file_offset, + obj_table_file_offset, + raw_code_file_offset, + escaped_name, + ): + self.mpy_source_file = mpy_source_file + self.mpy_segments = mpy_segments + self.source_file = qstr_table[0] + self.header = header + self.qstr_table = qstr_table + self.obj_table = obj_table + self.raw_code = raw_code + self.qstr_table_file_offset = qstr_table_file_offset + self.obj_table_file_offset = obj_table_file_offset + self.raw_code_file_offset = raw_code_file_offset + self.escaped_name = escaped_name + + def hexdump(self): + with open(self.mpy_source_file, "rb") as f: + WIDTH = 16 + COL_OFF = "\033[0m" + COL_TABLE = ( + ("", ""), # META + ("\033[0;31m", "\033[0;91m"), # QSTR + ("\033[0;32m", "\033[0;92m"), # OBJ + ("\033[0;34m", "\033[0;94m"), # CODE + ) + cur_col = "" + cur_col_index = 0 + offset = 0 + segment_index = 0 + while True: + data = bytes_cons(f.read(WIDTH)) + if not data: + break + + # Print out the hex dump of this line of data. + line_hex = cur_col + line_chr = cur_col + line_comment = "" + for i in range(len(data)): + # Determine the colour of the data, if any, and the line comment. + while segment_index < len(self.mpy_segments): + if offset + i == self.mpy_segments[segment_index].start: + cur_col = COL_TABLE[self.mpy_segments[segment_index].kind][ + cur_col_index + ] + cur_col_index = 1 - cur_col_index + line_hex += cur_col + line_chr += cur_col + line_comment += " %s%s%s" % ( + cur_col, + self.mpy_segments[segment_index].name, + COL_OFF, + ) + if offset + i == self.mpy_segments[segment_index].end: + cur_col = "" + line_hex += COL_OFF + line_chr += COL_OFF + segment_index += 1 + else: + break + + # Add to the hex part of the line. + if i % 2 == 0: + line_hex += " " + line_hex += "%02x" % data[i] + + # Add to the characters part of the line. + if 0x20 <= data[i] <= 0x7E: + line_chr += "%s" % chr(data[i]) + else: + line_chr += "." + + # Print out this line. + if cur_col: + line_hex += COL_OFF + line_chr += COL_OFF + pad = " " * ((WIDTH - len(data)) * 5 // 2) + print("%08x:%s%s %s %s" % (offset, line_hex, pad, line_chr, line_comment)) + offset += WIDTH + + def disassemble(self): + print("mpy_source_file:", self.mpy_source_file) + print("source_file:", self.source_file.str) + print("header:", hexlify_to_str(self.header)) + print("qstr_table[%u]:" % len(self.qstr_table)) + for q in self.qstr_table: + print(" %s" % q.str) + print("obj_table:", self.obj_table) + self.raw_code.disassemble() + + def freeze(self, compiled_module_index): + print() + print("/" * 80) + print("// frozen module %s" % self.escaped_name) + print("// - original source file: %s" % self.mpy_source_file) + print("// - frozen file name: %s" % self.source_file.str) + print("// - .mpy header: %s" % ":".join("%02x" % b for b in self.header)) + print() + + self.raw_code.freeze() + print() + + self.freeze_constants() + + print() + print("static const mp_frozen_module_t frozen_module_%s = {" % self.escaped_name) + print(" .constants = {") + if len(self.qstr_table): + print( + " .qstr_table = (qstr_short_t *)&const_qstr_table_data_%s," + % self.escaped_name + ) + else: + print(" .qstr_table = NULL,") + if len(self.obj_table): + print(" .obj_table = (mp_obj_t *)&const_obj_table_data_%s," % self.escaped_name) + else: + print(" .obj_table = NULL,") + print(" },") + print(" .rc = &raw_code_%s," % self.raw_code.escaped_name) + print("};") + + def freeze_constant_obj(self, obj_name, obj): + global const_str_content, const_int_content, const_obj_content + + if isinstance(obj, MPFunTable): + return "&mp_fun_table" + elif obj is None: + return "MP_ROM_NONE" + elif obj is False: + return "MP_ROM_FALSE" + elif obj is True: + return "MP_ROM_TRUE" + elif obj is Ellipsis: + return "MP_ROM_PTR(&mp_const_ellipsis_obj)" + elif is_str_type(obj) or is_bytes_type(obj): + if len(obj) == 0: + if is_str_type(obj): + return "MP_ROM_QSTR(MP_QSTR_)" + else: + return "MP_ROM_PTR(&mp_const_empty_bytes_obj)" + if is_str_type(obj): + q = global_qstrs.find_by_str(obj) + if q: + return "MP_ROM_QSTR(%s)" % q.qstr_id + obj = bytes_cons(obj, "utf8") + obj_type = "mp_type_str" + else: + obj_type = "mp_type_bytes" + print( + 'static const mp_obj_str_t %s = {{&%s}, %u, %u, (const byte*)"%s"};' + % ( + obj_name, + obj_type, + qstrutil.compute_hash(obj, config.MICROPY_QSTR_BYTES_IN_HASH), + len(obj), + "".join(("\\x%02x" % b) for b in obj), + ) + ) + const_str_content += len(obj) + const_obj_content += 4 * 4 + return "MP_ROM_PTR(&%s)" % obj_name + elif is_int_type(obj): + if mp_small_int_fits(obj): + # Encode directly as a small integer object. + return "MP_ROM_INT(%d)" % obj + elif config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_NONE: + raise FreezeError(self, "target does not support long int") + elif config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_LONGLONG: + # TODO + raise FreezeError(self, "freezing int to long-long is not implemented") + elif config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_MPZ: + neg = 0 + if obj < 0: + obj = -obj + neg = 1 + bits_per_dig = config.MPZ_DIG_SIZE + digs = [] + z = obj + while z: + digs.append(z & ((1 << bits_per_dig) - 1)) + z >>= bits_per_dig + ndigs = len(digs) + digs = ",".join(("%#x" % d) for d in digs) + print( + "static const mp_obj_int_t %s = {{&mp_type_int}, " + "{.neg=%u, .fixed_dig=1, .alloc=%u, .len=%u, .dig=(uint%u_t*)(const uint%u_t[]){%s}}};" + % (obj_name, neg, ndigs, ndigs, bits_per_dig, bits_per_dig, digs) + ) + const_int_content += (digs.count(",") + 1) * bits_per_dig // 8 + const_obj_content += 4 * 4 + return "MP_ROM_PTR(&%s)" % obj_name + elif type(obj) is float: + macro_name = "%s_macro" % obj_name + print( + "#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B" + ) + print( + "static const mp_obj_float_t %s = {{&mp_type_float}, (mp_float_t)%.16g};" + % (obj_name, obj) + ) + print("#define %s MP_ROM_PTR(&%s)" % (macro_name, obj_name)) + print("#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C") + n = struct.unpack(">= bits_per_dig - ndigs = len(digs) - digs = ",".join(("%#x" % d) for d in digs) - print( - "STATIC const mp_obj_int_t %s = {{&mp_type_int}, " - "{.neg=%u, .fixed_dig=1, .alloc=%u, .len=%u, .dig=(uint%u_t*)(const uint%u_t[]){%s}}};" - % (obj_name, neg, ndigs, ndigs, bits_per_dig, bits_per_dig, digs) - ) - elif type(obj) is float: - print( - "#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B" - ) - print( - "STATIC const mp_obj_float_t %s = {{&mp_type_float}, (mp_float_t)%.16g};" - % (obj_name, obj) - ) - print("#endif") - elif type(obj) is complex: - print( - "STATIC const mp_obj_complex_t %s = {{&mp_type_complex}, (mp_float_t)%.16g, (mp_float_t)%.16g};" - % (obj_name, obj.real, obj.imag) - ) - else: - raise FreezeError(self, "freezing of object %r is not implemented" % (obj,)) - - # generate constant table, if it has any entries - const_table_len = len(self.qstrs) + len(self.objs) + len(self.raw_codes) - if const_table_len: - print( - "STATIC const mp_rom_obj_t const_table_data_%s[%u] = {" - % (self.escaped_name, const_table_len) - ) - for qst in self.qstrs: - print(" MP_ROM_QSTR(%s)," % global_qstrs[qst].qstr_id) - for i in range(len(self.objs)): - if self.objs[i] is MPFunTable: - print(" &mp_fun_table,") - elif type(self.objs[i]) is float: - print( - "#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B" - ) - print(" MP_ROM_PTR(&const_obj_%s_%u)," % (self.escaped_name, i)) - print("#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C") - n = struct.unpack("> 8,") - print(" ", self.source_file.qstr_id, "& 0xff,", self.source_file.qstr_id, ">> 8,") - print(" ", end="") - for i in range(self.ip2 + 4, self.ip): - print(" 0x%02x," % self.bytecode[i], end="") - print() - ip = self.ip - while ip < len(self.bytecode): - f, sz = mp_opcode_format(self.bytecode, ip, True) - if f == 1: - qst = self._unpack_qstr(ip + 1).qstr_id - extra = "" if sz == 3 else " 0x%02x," % self.bytecode[ip + 3] - print(" ", "0x%02x," % self.bytecode[ip], qst, "& 0xff,", qst, ">> 8,", extra) - else: - print(" ", "".join("0x%02x, " % self.bytecode[ip + i] for i in range(sz))) + print("static const byte fun_data_%s[%u] = {" % (self.escaped_name, len(bc))) + + print(" ", end="") + for b in bc[: self.offset_source_info]: + print("0x%02x," % b, end="") + print(" // prelude") + + print(" ", end="") + for b in bc[self.offset_source_info : self.offset_line_info]: + print("0x%02x," % b, end="") + print(" // names: %s" % ", ".join(self.qstr_table[i].str for i in self.names)) + + print(" ", end="") + for b in bc[self.offset_line_info : self.offset_opcodes]: + print("0x%02x," % b, end="") + print(" // code info") + + ip = self.offset_opcodes + while ip < len(bc): + fmt, sz, arg, _ = mp_opcode_decode(bc, ip) + opcode_name = Opcode.mapping[bc[ip]] + if fmt == MP_BC_FORMAT_QSTR: + opcode_name += " " + repr(self.qstr_table[arg].str) + elif fmt in (MP_BC_FORMAT_VAR_UINT, MP_BC_FORMAT_OFFSET): + opcode_name += " %u" % arg + print( + " %s, // %s" % (",".join("0x%02x" % b for b in bc[ip : ip + sz]), opcode_name) + ) ip += sz + print("};") - self.freeze_constants() - self.freeze_module() + self.freeze_children() + self.freeze_raw_code() + + global bc_content + bc_content += len(bc) class RawCodeNative(RawCode): def __init__( self, - code_kind, + parent_name, + qstr_table, + kind, fun_data, prelude_offset, - prelude, - qstr_links, - qstrs, - objs, - raw_codes, + scope_flags, + n_pos_args, type_sig, ): super(RawCodeNative, self).__init__( - code_kind, fun_data, prelude_offset, qstrs, objs, raw_codes + parent_name, qstr_table, fun_data, prelude_offset, kind ) - self.prelude = prelude - self.qstr_links = qstr_links + + if kind in (MP_CODE_NATIVE_VIPER, MP_CODE_NATIVE_ASM): + self.scope_flags = scope_flags + self.n_pos_args = n_pos_args + self.type_sig = type_sig if config.native_arch in ( MP_NATIVE_ARCH_X86, @@ -484,322 +1076,328 @@ def __init__( # ARMVxxM -- two byte align. self.fun_data_attributes += " __attribute__ ((aligned (2)))" - def _asm_thumb_rewrite_mov(self, pc, val): - print(" (%u & 0xf0) | (%s >> 12)," % (self.bytecode[pc], val), end="") - print(" (%u & 0xfb) | (%s >> 9 & 0x04)," % (self.bytecode[pc + 1], val), end="") - print(" (%s & 0xff)," % (val,), end="") - print(" (%u & 0x07) | (%s >> 4 & 0x70)," % (self.bytecode[pc + 3], val)) - - def _link_qstr(self, pc, kind, qst): - if kind == 0: - # Generic 16-bit link - print(" %s & 0xff, %s >> 8," % (qst, qst)) - return 2 - else: - # Architecture-specific link - is_obj = kind == 2 - if is_obj: - qst = "((uintptr_t)MP_OBJ_NEW_QSTR(%s))" % qst - if config.native_arch in ( - MP_NATIVE_ARCH_X86, - MP_NATIVE_ARCH_X64, - MP_NATIVE_ARCH_ARMV6, - MP_NATIVE_ARCH_XTENSA, - MP_NATIVE_ARCH_XTENSAWIN, - ): - print( - " %s & 0xff, (%s >> 8) & 0xff, (%s >> 16) & 0xff, %s >> 24," - % (qst, qst, qst, qst) - ) - return 4 - elif MP_NATIVE_ARCH_ARMV6M <= config.native_arch <= MP_NATIVE_ARCH_ARMV7EMDP: - if is_obj: - # qstr object, movw and movt - self._asm_thumb_rewrite_mov(pc, qst) - self._asm_thumb_rewrite_mov(pc + 4, "(%s >> 16)" % qst) - return 8 - else: - # qstr number, movw instruction - self._asm_thumb_rewrite_mov(pc, qst) - return 4 - else: - assert 0 + def disassemble(self): + fun_data = self.fun_data + print("simple_name:", self.simple_name.str) + print( + " raw data:", + len(fun_data), + hexlify_to_str(fun_data[:32]), + "..." if len(fun_data) > 32 else "", + ) + if self.code_kind != MP_CODE_NATIVE_PY: + return + print(" prelude:", self.prelude_signature) + print(" args:", [self.qstr_table[i].str for i in self.names[1:]]) + print(" line info:", fun_data[self.offset_line_info : self.offset_opcodes]) + ip = 0 + while ip < self.prelude_offset: + sz = 16 + print(" ", hexlify_to_str(fun_data[ip : min(ip + sz, self.prelude_offset)])) + ip += sz + self.disassemble_children() - def freeze(self, parent_name): - if self.prelude[2] & ~0x0F: + def freeze(self): + if self.scope_flags & ~0x0F: raise FreezeError("unable to freeze code with relocations") - self.freeze_children(parent_name) - # generate native code data print() - if self.code_kind == MP_CODE_NATIVE_PY: - print( - "// frozen native code for file %s, scope %s%s" - % (self.source_file.str, parent_name, self.simple_name.str) - ) - elif self.code_kind == MP_CODE_NATIVE_VIPER: - print("// frozen viper code for scope %s" % (parent_name,)) - else: - print("// frozen assembler code for scope %s" % (parent_name,)) print( - "STATIC const byte fun_data_%s[%u] %s = {" - % (self.escaped_name, len(self.bytecode), self.fun_data_attributes) + "// frozen native code for file %s, scope %s" + % (self.qstr_table[0].str, self.escaped_name) + ) + print( + "static const byte fun_data_%s[%u] %s = {" + % (self.escaped_name, len(self.fun_data), self.fun_data_attributes) ) - if self.code_kind == MP_CODE_NATIVE_PY: - i_top = self.prelude_offset - else: - i_top = len(self.bytecode) + i_top = len(self.fun_data) i = 0 qi = 0 while i < i_top: - if qi < len(self.qstr_links) and i == self.qstr_links[qi][0]: - # link qstr - qi_off, qi_kind, qi_val = self.qstr_links[qi] - qst = global_qstrs[qi_val].qstr_id - i += self._link_qstr(i, qi_kind, qst) - qi += 1 - else: - # copy machine code (max 16 bytes) - i16 = min(i + 16, i_top) - if qi < len(self.qstr_links): - i16 = min(i16, self.qstr_links[qi][0]) - print(" ", end="") - for ii in range(i, i16): - print(" 0x%02x," % self.bytecode[ii], end="") - print() - i = i16 - - if self.code_kind == MP_CODE_NATIVE_PY: + # copy machine code (max 16 bytes) + i16 = min(i + 16, i_top) print(" ", end="") - for i in range(self.prelude_offset, self.ip2): - print(" 0x%02x," % self.bytecode[i], end="") + for ii in range(i, i16): + print(" 0x%02x," % self.fun_data[ii], end="") print() + i = i16 - print(" ", self.simple_name.qstr_id, "& 0xff,", self.simple_name.qstr_id, ">> 8,") - print(" ", self.source_file.qstr_id, "& 0xff,", self.source_file.qstr_id, ">> 8,") + print("};") - print(" ", end="") - for i in range(self.ip2 + 4, self.ip): - print(" 0x%02x," % self.bytecode[i], end="") - print() + prelude_ptr = None + if self.code_kind == MP_CODE_NATIVE_PY: + prelude_ptr = "fun_data_%s_prelude_macro" % self.escaped_name + print("#if MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE") + n = len(self.fun_data) - self.prelude_offset + print("static const byte fun_data_%s_prelude[%u] = {" % (self.escaped_name, n), end="") + for i in range(n): + print(" 0x%02x," % self.fun_data[self.prelude_offset + i], end="") + print("};") + print("#define %s &fun_data_%s_prelude[0]" % (prelude_ptr, self.escaped_name)) + print("#else") + print( + "#define %s &fun_data_%s[%u]" + % (prelude_ptr, self.escaped_name, self.prelude_offset) + ) + print("#endif") - print("};") + self.freeze_children(prelude_ptr) + self.freeze_raw_code(prelude_ptr, self.type_sig) - self.freeze_constants() - self.freeze_module(self.qstr_links, self.type_sig) +class MPYSegment: + META = 0 + QSTR = 1 + OBJ = 2 + CODE = 3 -class BytecodeBuffer: - def __init__(self, size): - self.buf = bytearray(size) - self.idx = 0 + def __init__(self, kind, name, start, end): + self.kind = kind + self.name = name + self.start = start + self.end = end - def is_full(self): - return self.idx == len(self.buf) - def append(self, b): - self.buf[self.idx] = b - self.idx += 1 +class MPYReader: + def __init__(self, filename, fileobj): + self.filename = filename + self.fileobj = fileobj + def tell(self): + return self.fileobj.tell() -def read_byte(f, out=None): - b = bytes_cons(f.read(1))[0] - if out is not None: - out.append(b) - return b + def read_byte(self): + return bytes_cons(self.fileobj.read(1))[0] + def read_bytes(self, n): + return bytes_cons(self.fileobj.read(n)) -def read_uint(f, out=None): - i = 0 - while True: - b = read_byte(f, out) - i = (i << 7) | (b & 0x7F) - if b & 0x80 == 0: - break - return i + def read_uint(self): + i = 0 + while True: + b = self.read_byte() + i = (i << 7) | (b & 0x7F) + if b & 0x80 == 0: + break + return i -def read_qstr(f, qstr_win): - ln = read_uint(f) - if ln == 0: - # static qstr - return bytes_cons(f.read(1))[0] +def read_qstr(reader, segments): + start_pos = reader.tell() + ln = reader.read_uint() if ln & 1: - # qstr in table - return qstr_win.access(ln >> 1) + # static qstr + q = global_qstrs.get_by_index(ln >> 1) + segments.append(MPYSegment(MPYSegment.META, q.str, start_pos, start_pos)) + return q ln >>= 1 - data = str_cons(f.read(ln), "utf8") - global_qstrs.append(QStrType(data)) - qstr_win.push(len(global_qstrs) - 1) - return len(global_qstrs) - 1 - - -def read_obj(f): - obj_type = f.read(1) - if obj_type == b"e": + start_pos = reader.tell() + data = str_cons(reader.read_bytes(ln), "utf8") + reader.read_byte() # read and discard null terminator + segments.append(MPYSegment(MPYSegment.QSTR, data, start_pos, reader.tell())) + return global_qstrs.add(data) + + +def read_obj(reader, segments): + obj_type = reader.read_byte() + if obj_type == MP_PERSISTENT_OBJ_FUN_TABLE: + return MPFunTable() + elif obj_type == MP_PERSISTENT_OBJ_NONE: + return None + elif obj_type == MP_PERSISTENT_OBJ_FALSE: + return False + elif obj_type == MP_PERSISTENT_OBJ_TRUE: + return True + elif obj_type == MP_PERSISTENT_OBJ_ELLIPSIS: return Ellipsis + elif obj_type == MP_PERSISTENT_OBJ_TUPLE: + ln = reader.read_uint() + return tuple(read_obj(reader, segments) for _ in range(ln)) else: - buf = f.read(read_uint(f)) - if obj_type == b"s": - return str_cons(buf, "utf8") - elif obj_type == b"b": - return bytes_cons(buf) - elif obj_type == b"i": - return int(str_cons(buf, "ascii"), 10) - elif obj_type == b"f": - return float(str_cons(buf, "ascii")) - elif obj_type == b"c": - return complex(str_cons(buf, "ascii")) + ln = reader.read_uint() + start_pos = reader.tell() + buf = reader.read_bytes(ln) + if obj_type in (MP_PERSISTENT_OBJ_STR, MP_PERSISTENT_OBJ_BYTES): + reader.read_byte() # read and discard null terminator + if obj_type == MP_PERSISTENT_OBJ_STR: + obj = str_cons(buf, "utf8") + if len(obj) < PERSISTENT_STR_INTERN_THRESHOLD: + if not global_qstrs.find_by_str(obj): + global_qstrs.add(obj) + elif obj_type == MP_PERSISTENT_OBJ_BYTES: + obj = buf + elif obj_type == MP_PERSISTENT_OBJ_INT: + obj = int(str_cons(buf, "ascii"), 10) + elif obj_type == MP_PERSISTENT_OBJ_FLOAT: + obj = float(str_cons(buf, "ascii")) + elif obj_type == MP_PERSISTENT_OBJ_COMPLEX: + obj = complex(str_cons(buf, "ascii")) else: - assert 0 + raise MPYReadError(reader.filename, "corrupt .mpy file") + segments.append(MPYSegment(MPYSegment.OBJ, obj, start_pos, reader.tell())) + return obj -def read_prelude(f, bytecode, qstr_win): - ( - n_state, - n_exc_stack, - scope_flags, - n_pos_args, - n_kwonly_args, - n_def_pos_args, - ) = read_prelude_sig(lambda: read_byte(f, bytecode)) - n_info, n_cell = read_prelude_size(lambda: read_byte(f, bytecode)) - read_qstr_and_pack(f, bytecode, qstr_win) # simple_name - read_qstr_and_pack(f, bytecode, qstr_win) # source_file - for _ in range(n_info - 4 + n_cell): - read_byte(f, bytecode) - return n_state, n_exc_stack, scope_flags, n_pos_args, n_kwonly_args, n_def_pos_args - - -def read_qstr_and_pack(f, bytecode, qstr_win): - qst = read_qstr(f, qstr_win) - bytecode.append(qst & 0xFF) - bytecode.append(qst >> 8) - - -def read_bytecode(file, bytecode, qstr_win): - while not bytecode.is_full(): - op = read_byte(file, bytecode) - f, sz = mp_opcode_format(bytecode.buf, bytecode.idx - 1, False) - sz -= 1 - if f == MP_BC_FORMAT_QSTR: - read_qstr_and_pack(file, bytecode, qstr_win) - sz -= 2 - elif f == MP_BC_FORMAT_VAR_UINT: - while read_byte(file, bytecode) & 0x80: - pass - for _ in range(sz): - read_byte(file, bytecode) - - -def read_raw_code(f, qstr_win): - kind_len = read_uint(f) +def read_raw_code(reader, parent_name, qstr_table, obj_table, segments): + # Read raw code header. + kind_len = reader.read_uint() kind = (kind_len & 3) + MP_CODE_BYTECODE - fun_data_len = kind_len >> 2 - fun_data = BytecodeBuffer(fun_data_len) + has_children = (kind_len >> 2) & 1 + fun_data_len = kind_len >> 3 + + # Read the body of the raw code. + file_offset = reader.tell() + fun_data = reader.read_bytes(fun_data_len) + segments_len = len(segments) if kind == MP_CODE_BYTECODE: - prelude = read_prelude(f, fun_data, qstr_win) - read_bytecode(f, fun_data, qstr_win) + # Create bytecode raw code. + rc = RawCodeBytecode(parent_name, qstr_table, obj_table, fun_data) else: - fun_data.buf[:] = f.read(fun_data_len) - - qstr_links = [] - if kind in (MP_CODE_NATIVE_PY, MP_CODE_NATIVE_VIPER): - # load qstr link table - n_qstr_link = read_uint(f) - for _ in range(n_qstr_link): - off = read_uint(f) - qst = read_qstr(f, qstr_win) - qstr_links.append((off >> 2, off & 3, qst)) - - type_sig = 0 + # Create native raw code. + native_scope_flags = 0 + native_n_pos_args = 0 + native_type_sig = 0 if kind == MP_CODE_NATIVE_PY: - prelude_offset = read_uint(f) - _, name_idx, prelude = extract_prelude(fun_data.buf, prelude_offset) - fun_data.idx = name_idx # rewind to where qstrs are in prelude - read_qstr_and_pack(f, fun_data, qstr_win) # simple_name - read_qstr_and_pack(f, fun_data, qstr_win) # source_file + prelude_offset = reader.read_uint() else: - prelude_offset = None - scope_flags = read_uint(f) - n_pos_args = 0 - if kind == MP_CODE_NATIVE_ASM: - n_pos_args = read_uint(f) - type_sig = read_uint(f) - prelude = (None, None, scope_flags, n_pos_args, 0) - - qstrs = [] - objs = [] - raw_codes = [] - if kind != MP_CODE_NATIVE_ASM: - # load constant table - n_obj = read_uint(f) - n_raw_code = read_uint(f) - qstrs = [read_qstr(f, qstr_win) for _ in range(prelude[3] + prelude[4])] - if kind != MP_CODE_BYTECODE: - objs.append(MPFunTable) - objs.extend([read_obj(f) for _ in range(n_obj)]) - raw_codes = [read_raw_code(f, qstr_win) for _ in range(n_raw_code)] + prelude_offset = 0 + native_scope_flags = reader.read_uint() + if kind == MP_CODE_NATIVE_VIPER: + # Read any additional sections for native viper. + if native_scope_flags & MP_SCOPE_FLAG_VIPERRODATA: + rodata_size = reader.read_uint() + if native_scope_flags & MP_SCOPE_FLAG_VIPERBSS: + bss_size = reader.read_uint() + if native_scope_flags & MP_SCOPE_FLAG_VIPERRODATA: + reader.read_bytes(rodata_size) + if native_scope_flags & MP_SCOPE_FLAG_VIPERRELOC: + while True: + op = reader.read_byte() + if op == 0xFF: + break + if op & 1: + addr = reader.read_uint() + op >>= 1 + if op <= 5 and op & 1: + n = reader.read_uint() + else: + assert kind == MP_CODE_NATIVE_ASM + native_n_pos_args = reader.read_uint() + native_type_sig = reader.read_uint() - if kind == MP_CODE_BYTECODE: - return RawCodeBytecode(fun_data.buf, qstrs, objs, raw_codes) - else: - return RawCodeNative( + rc = RawCodeNative( + parent_name, + qstr_table, kind, - fun_data.buf, + fun_data, prelude_offset, - prelude, - qstr_links, - qstrs, - objs, - raw_codes, - type_sig, + native_scope_flags, + native_n_pos_args, + native_type_sig, ) + # Add a segment for the raw code data. + segments.insert( + segments_len, + MPYSegment(MPYSegment.CODE, rc.simple_name.str, file_offset, file_offset + fun_data_len), + ) + + # Read children, if there are any. + rc.children = [] + if has_children: + # Make a pretty parent name (otherwise all identifiers will include _lt_module_gt_). + if not rc.escaped_name.endswith("_lt_module_gt_"): + parent_name = rc.escaped_name + + # Read all the child raw codes. + n_children = reader.read_uint() + for _ in range(n_children): + rc.children.append(read_raw_code(reader, parent_name, qstr_table, obj_table, segments)) + + return rc + def read_mpy(filename): - with open(filename, "rb") as f: - header = bytes_cons(f.read(4)) + with open(filename, "rb") as fileobj: + reader = MPYReader(filename, fileobj) + segments = [] + + # Read and verify the header. + header = reader.read_bytes(4) if header[0] != ord("C"): - raise Exception("not a valid CircuitPython .mpy file") + raise MPYReadError(filename, "not a valid .mpy file") if header[1] != config.MPY_VERSION: - raise Exception("incompatible .mpy version") + raise MPYReadError(filename, "incompatible .mpy version") feature_byte = header[2] - qw_size = read_uint(f) - config.MICROPY_PY_BUILTINS_STR_UNICODE = (feature_byte & 2) != 0 mpy_native_arch = feature_byte >> 2 if mpy_native_arch != MP_NATIVE_ARCH_NONE: if config.native_arch == MP_NATIVE_ARCH_NONE: config.native_arch = mpy_native_arch elif config.native_arch != mpy_native_arch: - raise Exception("native architecture mismatch") + raise MPYReadError(filename, "native architecture mismatch") config.mp_small_int_bits = header[3] - qstr_win = QStrWindow(qw_size) - rc = read_raw_code(f, qstr_win) - rc.mpy_source_file = filename - rc.qstr_win_size = qw_size - return rc + # Read number of qstrs, and number of objects. + n_qstr = reader.read_uint() + n_obj = reader.read_uint() + + # Read qstrs and construct qstr table. + qstr_table_file_offset = reader.tell() + qstr_table = [] + for i in range(n_qstr): + qstr_table.append(read_qstr(reader, segments)) + + # Read objects and construct object table. + obj_table_file_offset = reader.tell() + obj_table = [] + for i in range(n_obj): + obj_table.append(read_obj(reader, segments)) + + # Compute the compiled-module escaped name. + cm_escaped_name = qstr_table[0].str.replace("/", "_")[:-3] + + # Read the outer raw code, which will in turn read all its children. + raw_code_file_offset = reader.tell() + raw_code = read_raw_code(reader, cm_escaped_name, qstr_table, obj_table, segments) + + # Create the outer-level compiled module representing the whole .mpy file. + return CompiledModule( + filename, + segments, + header, + qstr_table, + obj_table, + raw_code, + qstr_table_file_offset, + obj_table_file_offset, + raw_code_file_offset, + cm_escaped_name, + ) + + +def hexdump_mpy(compiled_modules): + for cm in compiled_modules: + cm.hexdump() -def dump_mpy(raw_codes): - for rc in raw_codes: - rc.dump() +def disassemble_mpy(compiled_modules): + for cm in compiled_modules: + cm.disassemble() -def freeze_mpy(base_qstrs, raw_codes): + +def freeze_mpy(base_qstrs, compiled_modules): # add to qstrs new = {} - for q in global_qstrs: + for q in global_qstrs.qstrs: # don't add duplicates if q is None or q.qstr_esc in base_qstrs or q.qstr_esc in new: continue - new[q.qstr_esc] = (len(new), q.qstr_esc, q.str) + new[q.qstr_esc] = (len(new), q.qstr_esc, q.str, bytes_cons(q.str, "utf8")) new = sorted(new.values(), key=lambda x: x[0]) - print('#include "py/bc0.h"') print('#include "py/mpconfig.h"') print('#include "py/objint.h"') print('#include "py/objstr.h"') @@ -835,7 +1433,7 @@ def freeze_mpy(base_qstrs, raw_codes): print("#endif") print() - if new: + if len(new) > 0: print("enum {") for i in range(len(new)): if i == 0: @@ -844,24 +1442,36 @@ def freeze_mpy(base_qstrs, raw_codes): print(" MP_QSTR_%s," % new[i][1]) print("};") + # As in qstr.c, set so that the first dynamically allocated pool is twice this size; must be <= the len + qstr_pool_alloc = min(len(new), 10) + + global bc_content, const_str_content, const_int_content, const_obj_content, const_table_qstr_content, const_table_ptr_content, raw_code_count, raw_code_content + qstr_content = 0 + bc_content = 0 + const_str_content = 0 + const_int_content = 0 + const_obj_content = 0 + const_table_qstr_content = 0 + const_table_ptr_content = 0 + raw_code_count = 0 + raw_code_content = 0 + print() - print("const qstr_attr_t mp_qstr_frozen_const_attr[] = {") + print("const qstr_hash_t mp_qstr_frozen_const_hashes[] = {") qstr_size = {"metadata": 0, "data": 0} - for _, _, qstr in new: - qbytes = qstrutil.bytes_cons(qstr, "utf8") - print( - " {%d, %d}," - % (qstrutil.compute_hash(qbytes, config.MICROPY_QSTR_BYTES_IN_HASH), len(qbytes)) - ) + for _, _, _, qbytes in new: + qhash = qstrutil.compute_hash(qbytes, config.MICROPY_QSTR_BYTES_IN_HASH) + print(" %d," % qhash) + print("};") + print() + print("const qstr_len_t mp_qstr_frozen_const_lengths[] = {") + for _, _, _, qbytes in new: + print(" %d," % len(qbytes)) qstr_size["metadata"] += ( config.MICROPY_QSTR_BYTES_IN_LEN + config.MICROPY_QSTR_BYTES_IN_HASH ) qstr_size["data"] += len(qbytes) print("};") - - # As in qstr.c, set so that the first dynamically allocated pool is twice this size; must be <= the len - qstr_pool_alloc = min(len(new), 10) - print() print("extern const qstr_pool_t mp_qstr_const_pool;") print("const qstr_pool_t mp_qstr_frozen_const_pool = {") @@ -869,36 +1479,54 @@ def freeze_mpy(base_qstrs, raw_codes): print(" MP_QSTRnumber_of, // previous pool size") print(" %u, // allocated entries" % qstr_pool_alloc) print(" %u, // used entries" % len(new)) - print(" (qstr_attr_t *)mp_qstr_frozen_const_attr,") + print(" (qstr_hash_t *)mp_qstr_frozen_const_hashes,") + print(" (qstr_len_t *)mp_qstr_frozen_const_lengths,") print(" {") - for _, _, qstr in new: - print(' "%s",' % qstrutil.escape_bytes(qstr)) + for _, _, qstr, qbytes in new: + print(' "%s",' % qstrutil.escape_bytes(qstr, qbytes)) + qstr_content += ( + config.MICROPY_QSTR_BYTES_IN_LEN + config.MICROPY_QSTR_BYTES_IN_HASH + len(qbytes) + 1 + ) print(" },") print("};") - for rc in raw_codes: - rc.freeze(rc.source_file.str.replace("/", "_")[:-3] + "_") + # Freeze all modules. + for idx, cm in enumerate(compiled_modules): + cm.freeze(idx) + + # Print separator, separating individual modules from global data structures. + print() + print("/" * 80) + print("// collection of all frozen modules") + # Define the string of frozen module names. print() print("const char mp_frozen_names[] = {") - print("#ifdef MP_FROZEN_STR_NAMES") + print(" #ifdef MP_FROZEN_STR_NAMES") # makemanifest.py might also include some frozen string content. - print("MP_FROZEN_STR_NAMES") - print("#endif") - for rc in raw_codes: - module_name = rc.source_file.str - print('"%s\\0"' % module_name) - print('"\\0"};') - - print("const mp_raw_code_t *const mp_frozen_mpy_content[] = {") - for rc in raw_codes: - print(" &raw_code_%s," % rc.escaped_name) + print(" MP_FROZEN_STR_NAMES") + print(" #endif") + mp_frozen_mpy_names_content = 1 + for cm in compiled_modules: + module_name = cm.source_file.str + print(' "%s\\0"' % module_name) + mp_frozen_mpy_names_content += len(cm.source_file.str) + 1 + print(' "\\0"') print("};") + # Define the array of pointers to frozen module content. + print() + print("const mp_frozen_module_t *const mp_frozen_mpy_content[] = {") + for cm in compiled_modules: + print(" &frozen_module_%s," % cm.escaped_name) + print("};") + mp_frozen_mpy_content_size = len(compiled_modules * 4) + # If a port defines MICROPY_FROZEN_LIST_ITEM then list all modules wrapped in that macro. + print() print("#ifdef MICROPY_FROZEN_LIST_ITEM") - for rc in raw_codes: - module_name = rc.source_file.str + for cm in compiled_modules: + module_name = cm.source_file.str if module_name.endswith("/__init__.py"): short_name = module_name[: -len("/__init__.py")] else: @@ -906,47 +1534,189 @@ def freeze_mpy(base_qstrs, raw_codes): print('MICROPY_FROZEN_LIST_ITEM("%s", "%s")' % (short_name, module_name)) print("#endif") - -def merge_mpy(raw_codes, output_file): - assert len(raw_codes) <= 31 # so var-uints all fit in 1 byte + print() + print("/*") + print("byte sizes:") + print("qstr content: %d unique, %d bytes" % (len(new), qstr_content)) + print("bc content: %d" % bc_content) + print("const str content: %d" % const_str_content) + print("const int content: %d" % const_int_content) + print("const obj content: %d" % const_obj_content) + print( + "const table qstr content: %d entries, %d bytes" + % (const_table_qstr_content, const_table_qstr_content * 4) + ) + print( + "const table ptr content: %d entries, %d bytes" + % (const_table_ptr_content, const_table_ptr_content * 4) + ) + print("raw code content: %d * 4 = %d" % (raw_code_count, raw_code_content)) + print("mp_frozen_mpy_names_content: %d" % mp_frozen_mpy_names_content) + print("mp_frozen_mpy_content_size: %d" % mp_frozen_mpy_content_size) + print( + "total: %d" + % ( + qstr_content + + bc_content + + const_str_content + + const_int_content + + const_obj_content + + const_table_qstr_content * 4 + + const_table_ptr_content * 4 + + raw_code_content + + mp_frozen_mpy_names_content + + mp_frozen_mpy_content_size + ) + ) + print("*/") + + +def adjust_bytecode_qstr_obj_indices(bytecode_in, qstr_table_base, obj_table_base): + # Expand bytcode to a list of opcodes. + opcodes = [] + labels = {} + ip = 0 + while ip < len(bytecode_in): + fmt, sz, arg, extra_arg = mp_opcode_decode(bytecode_in, ip) + opcode = Opcode(ip, fmt, bytecode_in[ip], arg, extra_arg) + labels[ip] = opcode + opcodes.append(opcode) + ip += sz + if fmt == MP_BC_FORMAT_OFFSET: + opcode.arg += ip + + # Link jump opcodes to their destination. + for opcode in opcodes: + if opcode.fmt == MP_BC_FORMAT_OFFSET: + opcode.target = labels[opcode.arg] + + # Adjust bytcode as required. + for opcode in opcodes: + if opcode.fmt == MP_BC_FORMAT_QSTR: + opcode.arg += qstr_table_base + elif opcode.opcode_byte == Opcode.MP_BC_LOAD_CONST_OBJ: + opcode.arg += obj_table_base + + # Write out new bytecode. + offset_changed = True + while offset_changed: + offset_changed = False + overflow = False + bytecode_out = b"" + for opcode in opcodes: + ip = len(bytecode_out) + if opcode.offset != ip: + offset_changed = True + opcode.offset = ip + opcode_overflow, encoded_opcode = mp_opcode_encode(opcode) + if opcode_overflow: + overflow = True + bytecode_out += encoded_opcode + + if overflow: + raise Exception("bytecode overflow") + + return bytecode_out + + +def rewrite_raw_code(rc, qstr_table_base, obj_table_base): + if rc.code_kind != MP_CODE_BYTECODE: + raise Exception("can only rewrite bytecode") + + source_info = bytearray() + for arg in rc.names: + source_info.extend(mp_encode_uint(qstr_table_base + arg)) + + closure_info = rc.fun_data[rc.offset_closure_info : rc.offset_opcodes] + + bytecode_in = memoryview(rc.fun_data)[rc.offset_opcodes :] + bytecode_out = adjust_bytecode_qstr_obj_indices(bytecode_in, qstr_table_base, obj_table_base) + + prelude_signature = rc.fun_data[: rc.offset_prelude_size] + prelude_size = encode_prelude_size(len(source_info), len(closure_info)) + + fun_data = prelude_signature + prelude_size + source_info + closure_info + bytecode_out + + output = mp_encode_uint(len(fun_data) << 3 | bool(len(rc.children)) << 2) + output += fun_data + + if rc.children: + output += mp_encode_uint(len(rc.children)) + for child in rc.children: + output += rewrite_raw_code(child, qstr_table_base, obj_table_base) + + return output + + +def merge_mpy(compiled_modules, output_file): merged_mpy = bytearray() - if len(raw_codes) == 1: - with open(raw_codes[0].mpy_source_file, "rb") as f: + if len(compiled_modules) == 1: + with open(compiled_modules[0].mpy_source_file, "rb") as f: merged_mpy.extend(f.read()) else: - header = bytearray(5) + main_cm_idx = None + for idx, cm in enumerate(compiled_modules): + if cm.header[2]: + # Must use qstr_table and obj_table from this raw_code + if main_cm_idx is not None: + raise Exception("can't merge files when more than one contains native code") + main_cm_idx = idx + if main_cm_idx is not None: + # Shift main_cm to front of list. + compiled_modules.insert(0, compiled_modules.pop(main_cm_idx)) + + header = bytearray(4) header[0] = ord("C") header[1] = config.MPY_VERSION - header[2] = config.native_arch << 2 | config.MICROPY_PY_BUILTINS_STR_UNICODE << 1 + header[2] = config.native_arch << 2 header[3] = config.mp_small_int_bits - header[4] = 32 # qstr_win_size merged_mpy.extend(header) + n_qstr = 0 + n_obj = 0 + for cm in compiled_modules: + n_qstr += len(cm.qstr_table) + n_obj += len(cm.obj_table) + merged_mpy.extend(mp_encode_uint(n_qstr)) + merged_mpy.extend(mp_encode_uint(n_obj)) + + # Copy verbatim the qstr and object tables from all compiled modules. + def copy_section(file, offset, offset2): + with open(file, "rb") as f: + f.seek(offset) + merged_mpy.extend(f.read(offset2 - offset)) + + for cm in compiled_modules: + copy_section(cm.mpy_source_file, cm.qstr_table_file_offset, cm.obj_table_file_offset) + for cm in compiled_modules: + copy_section(cm.mpy_source_file, cm.obj_table_file_offset, cm.raw_code_file_offset) + bytecode = bytearray() - bytecode_len = 6 + len(raw_codes) * 5 + 2 - bytecode.append(bytecode_len << 2) # kind and length - bytecode.append(0b00000000) # signature prelude - bytecode.append(0b00001000) # size prelude - bytecode.extend(b"\x00\x01") # MP_QSTR_ - bytecode.extend(b"\x00\x01") # MP_QSTR_ - for idx in range(len(raw_codes)): + bytecode.append(0b00000000) # prelude signature + bytecode.append(0b00000010) # prelude size (n_info=1, n_cell=0) + bytecode.extend(b"\x00") # simple_name: qstr index 0 (will use source filename) + for idx in range(len(compiled_modules)): bytecode.append(0x32) # MP_BC_MAKE_FUNCTION bytecode.append(idx) # index raw code bytecode.extend(b"\x34\x00\x59") # MP_BC_CALL_FUNCTION, 0 args, MP_BC_POP_TOP bytecode.extend(b"\x51\x63") # MP_BC_LOAD_NONE, MP_BC_RETURN_VALUE - bytecode.append(0) # n_obj - bytecode.append(len(raw_codes)) # n_raw_code - + merged_mpy.extend(mp_encode_uint(len(bytecode) << 3 | 1 << 2)) # length, has_children merged_mpy.extend(bytecode) - - for rc in raw_codes: - with open(rc.mpy_source_file, "rb") as f: - f.read(4) # skip header - read_uint(f) # skip qstr_win_size - data = f.read() # read rest of mpy file - merged_mpy.extend(data) + merged_mpy.extend(mp_encode_uint(len(compiled_modules))) # n_children + + qstr_table_base = 0 + obj_table_base = 0 + for cm in compiled_modules: + if qstr_table_base == 0 and obj_table_base == 0: + with open(cm.mpy_source_file, "rb") as f: + f.seek(cm.raw_code_file_offset) + merged_mpy.extend(f.read()) + else: + merged_mpy.extend(rewrite_raw_code(cm.raw_code, qstr_table_base, obj_table_base)) + qstr_table_base += len(cm.qstr_table) + obj_table_base += len(cm.obj_table) if output_file is None: sys.stdout.buffer.write(merged_mpy) @@ -956,10 +1726,17 @@ def merge_mpy(raw_codes, output_file): def main(): + global global_qstrs + import argparse cmd_parser = argparse.ArgumentParser(description="A tool to work with MicroPython .mpy files.") - cmd_parser.add_argument("-d", "--dump", action="store_true", help="dump contents of files") + cmd_parser.add_argument( + "-x", "--hexdump", action="store_true", help="output an annotated hex dump of files" + ) + cmd_parser.add_argument( + "-d", "--disassemble", action="store_true", help="output disassembled contents of files" + ) cmd_parser.add_argument("-f", "--freeze", action="store_true", help="freeze files") cmd_parser.add_argument( "--merge", action="store_true", help="merge multiple .mpy files into one" @@ -993,26 +1770,41 @@ def main(): # set config values for qstrs, and get the existing base set of qstrs if args.qstr_header: - qcfgs, base_qstrs, _ = qstrutil.parse_input_headers([args.qstr_header]) + qcfgs, base_qstrs = qstrutil.parse_input_headers([args.qstr_header]) config.MICROPY_QSTR_BYTES_IN_LEN = int(qcfgs["BYTES_IN_LEN"]) config.MICROPY_QSTR_BYTES_IN_HASH = int(qcfgs["BYTES_IN_HASH"]) else: config.MICROPY_QSTR_BYTES_IN_LEN = 1 config.MICROPY_QSTR_BYTES_IN_HASH = 1 - base_qstrs = {} + base_qstrs = list(qstrutil.static_qstr_list) + + # Create initial list of global qstrs. + global_qstrs = GlobalQStrList() - raw_codes = [read_mpy(file) for file in args.files] + # Load all .mpy files. + try: + compiled_modules = [read_mpy(file) for file in args.files] + except MPYReadError as er: + print(er, file=sys.stderr) + sys.exit(1) - if args.dump: - dump_mpy(raw_codes) - elif args.freeze: + if args.hexdump: + hexdump_mpy(compiled_modules) + + if args.disassemble: + if args.hexdump: + print() + disassemble_mpy(compiled_modules) + + if args.freeze: try: - freeze_mpy(base_qstrs, raw_codes) + freeze_mpy(base_qstrs, compiled_modules) except FreezeError as er: print(er, file=sys.stderr) sys.exit(1) - elif args.merge: - merged_mpy = merge_mpy(raw_codes, args.output) + + if args.merge: + merge_mpy(compiled_modules, args.output) if __name__ == "__main__": diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index 54df98ef07201..4d01f52df802b 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -35,22 +35,23 @@ import makeqstrdata as qstrutil # MicroPython constants -MPY_VERSION = 5 +MPY_VERSION = 6 +MP_CODE_BYTECODE = 2 +MP_CODE_NATIVE_VIPER = 4 MP_NATIVE_ARCH_X86 = 1 MP_NATIVE_ARCH_X64 = 2 +MP_NATIVE_ARCH_ARMV6M = 4 MP_NATIVE_ARCH_ARMV7M = 5 MP_NATIVE_ARCH_ARMV7EMSP = 7 MP_NATIVE_ARCH_ARMV7EMDP = 8 MP_NATIVE_ARCH_XTENSA = 9 MP_NATIVE_ARCH_XTENSAWIN = 10 -MP_CODE_BYTECODE = 2 -MP_CODE_NATIVE_VIPER = 4 +MP_PERSISTENT_OBJ_STR = 5 +# Circuitpython: this does not match upstream because we added MP_SCOPE_FLAG_ASYNC MP_SCOPE_FLAG_VIPERRELOC = 0x20 MP_SCOPE_FLAG_VIPERRODATA = 0x40 MP_SCOPE_FLAG_VIPERBSS = 0x80 -MICROPY_PY_BUILTINS_STR_UNICODE = 2 MP_SMALL_INT_BITS = 31 -QSTR_WINDOW_SIZE = 32 # ELF constants R_386_32 = 1 @@ -75,6 +76,7 @@ R_X86_64_GOTPCREL = 9 R_X86_64_REX_GOTPCRELX = 42 R_386_GOT32X = 43 +R_XTENSA_PDIFF32 = 59 ################################################################################ # Architecture configuration @@ -84,7 +86,14 @@ def asm_jump_x86(entry): return struct.pack("> 11 == 0 or b_off >> 11 == -1, b_off + return struct.pack("> 1 & 0x07FF)) + + +def asm_jump_thumb2(entry): b_off = entry - 4 if b_off >> 11 == 0 or b_off >> 11 == -1: # Signed value fits in 12 bits @@ -104,72 +113,73 @@ def asm_jump_xtensa(entry): class ArchData: - def __init__(self, name, mpy_feature, qstr_entry_size, word_size, arch_got, asm_jump): + def __init__(self, name, mpy_feature, word_size, arch_got, asm_jump, *, separate_rodata=False): self.name = name self.mpy_feature = mpy_feature - self.qstr_entry_size = qstr_entry_size + self.qstr_entry_size = 2 self.word_size = word_size self.arch_got = arch_got self.asm_jump = asm_jump - self.separate_rodata = name == "EM_XTENSA" and qstr_entry_size == 4 + self.separate_rodata = separate_rodata ARCH_DATA = { "x86": ArchData( "EM_386", - MP_NATIVE_ARCH_X86 << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, - 2, + MP_NATIVE_ARCH_X86 << 2, 4, (R_386_PC32, R_386_GOT32, R_386_GOT32X), asm_jump_x86, ), "x64": ArchData( "EM_X86_64", - MP_NATIVE_ARCH_X64 << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, - 2, + MP_NATIVE_ARCH_X64 << 2, 8, (R_X86_64_GOTPCREL, R_X86_64_REX_GOTPCRELX), asm_jump_x86, ), + "armv6m": ArchData( + "EM_ARM", + MP_NATIVE_ARCH_ARMV6M << 2, + 4, + (R_ARM_GOT_BREL,), + asm_jump_thumb, + ), "armv7m": ArchData( "EM_ARM", - MP_NATIVE_ARCH_ARMV7M << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, - 2, + MP_NATIVE_ARCH_ARMV7M << 2, 4, (R_ARM_GOT_BREL,), - asm_jump_arm, + asm_jump_thumb2, ), "armv7emsp": ArchData( "EM_ARM", - MP_NATIVE_ARCH_ARMV7EMSP << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, - 2, + MP_NATIVE_ARCH_ARMV7EMSP << 2, 4, (R_ARM_GOT_BREL,), - asm_jump_arm, + asm_jump_thumb2, ), "armv7emdp": ArchData( "EM_ARM", - MP_NATIVE_ARCH_ARMV7EMDP << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, - 2, + MP_NATIVE_ARCH_ARMV7EMDP << 2, 4, (R_ARM_GOT_BREL,), - asm_jump_arm, + asm_jump_thumb2, ), "xtensa": ArchData( "EM_XTENSA", - MP_NATIVE_ARCH_XTENSA << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, - 2, + MP_NATIVE_ARCH_XTENSA << 2, 4, (R_XTENSA_32, R_XTENSA_PLT), asm_jump_xtensa, ), "xtensawin": ArchData( "EM_XTENSA", - MP_NATIVE_ARCH_XTENSAWIN << 2 | MICROPY_PY_BUILTINS_STR_UNICODE, - 4, + MP_NATIVE_ARCH_XTENSAWIN << 2, 4, (R_XTENSA_32, R_XTENSA_PLT), asm_jump_xtensa, + separate_rodata=True, ), } @@ -421,10 +431,12 @@ def populate_got(env): # Create a relocation for each GOT entry for got_entry in got_list: - if got_entry.name == "mp_fun_table": - dest = "mp_fun_table" + if got_entry.name in ("mp_native_qstr_table", "mp_native_obj_table", "mp_fun_table"): + dest = got_entry.name elif got_entry.name.startswith("mp_fun_table+0x"): dest = int(got_entry.name.split("+")[1], 16) // env.arch.word_size + elif got_entry.sec_name == ".external.mp_fun_table": + dest = got_entry.sym.mp_fun_table_offset elif got_entry.sec_name.startswith(".text"): dest = ".text" elif got_entry.sec_name.startswith(".rodata"): @@ -564,9 +576,9 @@ def do_relocation_text(env, text_addr, r): reloc = addr - r_offset reloc_type = "xtensa_l32r" - elif env.arch.name == "EM_XTENSA" and r_info_type == R_XTENSA_DIFF32: + elif env.arch.name == "EM_XTENSA" and r_info_type in (R_XTENSA_DIFF32, R_XTENSA_PDIFF32): if s.section.name.startswith(".text"): - # it looks like R_XTENSA_DIFF32 into .text is already correctly relocated + # it looks like R_XTENSA_[P]DIFF32 into .text is already correctly relocated return assert 0 @@ -740,23 +752,24 @@ def link_objects(env, native_qstr_vals_len, native_qstr_objs_len): env.lit_section = Section("LIT", bytearray(lit_size), env.arch.word_size) env.sections.insert(1, env.lit_section) - # Create section to contain mp_native_qstr_val_table - env.qstr_val_section = Section( - ".text.QSTR_VAL", + # Create section to contain mp_native_qstr_table + env.qstr_table_section = Section( + ".external.qstr_table", bytearray(native_qstr_vals_len * env.arch.qstr_entry_size), env.arch.qstr_entry_size, ) - env.sections.append(env.qstr_val_section) - # Create section to contain mp_native_qstr_obj_table - env.qstr_obj_section = Section( - ".text.QSTR_OBJ", bytearray(native_qstr_objs_len * env.arch.word_size), env.arch.word_size + # Create section to contain mp_native_obj_table + env.obj_table_section = Section( + ".external.obj_table", + bytearray(native_qstr_objs_len * env.arch.word_size), + env.arch.word_size, ) - env.sections.append(env.qstr_obj_section) # Resolve unknown symbols mp_fun_table_sec = Section(".external.mp_fun_table", b"", 0) fun_table = { + # Circuitpython: this does not match upstream because we added an item in _mp_fnu_table_t key: 68 + idx for idx, key in enumerate( [ @@ -782,10 +795,10 @@ def link_objects(env, native_qstr_vals_len, native_qstr_objs_len): pass elif sym.name == "mp_fun_table": sym.section = Section(".external", b"", 0) - elif sym.name == "mp_native_qstr_val_table": - sym.section = env.qstr_val_section - elif sym.name == "mp_native_qstr_obj_table": - sym.section = env.qstr_obj_section + elif sym.name == "mp_native_qstr_table": + sym.section = env.qstr_table_section + elif sym.name == "mp_native_obj_table": + sym.section = env.obj_table_section elif sym.name in env.known_syms: sym.resolved = env.known_syms[sym.name] else: @@ -860,11 +873,12 @@ def write_uint(self, val): def write_qstr(self, s): if s in qstrutil.static_qstr_list: - self.write_bytes(bytes([0, qstrutil.static_qstr_list.index(s) + 1])) + self.write_uint((qstrutil.static_qstr_list.index(s) + 1) << 1 | 1) else: s = bytes(s, "ascii") self.write_uint(len(s) << 1) self.write_bytes(s) + self.write_bytes(b"\x00") def write_reloc(self, base, offset, dest, n): need_offset = not (base == self.prev_base and offset == self.prev_offset + 1) @@ -905,35 +919,31 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs): out.open(fmpy) # MPY: header - out.write_bytes( - bytearray( - [ - ord("C"), - MPY_VERSION, - env.arch.mpy_feature, - MP_SMALL_INT_BITS, - QSTR_WINDOW_SIZE, - ] - ) - ) + out.write_bytes(bytearray([ord("C"), MPY_VERSION, env.arch.mpy_feature, MP_SMALL_INT_BITS])) + + # MPY: n_qstr + out.write_uint(1 + len(native_qstr_vals)) + + # MPY: n_obj + out.write_uint(len(native_qstr_objs)) + + # MPY: qstr table + out.write_qstr(fmpy) # filename + for q in native_qstr_vals: + out.write_qstr(q) + + # MPY: object table + for q in native_qstr_objs: + out.write_bytes(bytearray([MP_PERSISTENT_OBJ_STR])) + out.write_uint(len(q)) + out.write_bytes(bytes(q, "utf8") + b"\x00") # MPY: kind/len - out.write_uint(len(env.full_text) << 2 | (MP_CODE_NATIVE_VIPER - MP_CODE_BYTECODE)) + out.write_uint(len(env.full_text) << 3 | (MP_CODE_NATIVE_VIPER - MP_CODE_BYTECODE)) # MPY: machine code 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 scope_flags = MP_SCOPE_FLAG_VIPERRELOC if len(env.full_rodata): @@ -942,20 +952,15 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs): scope_flags |= MP_SCOPE_FLAG_VIPERBSS out.write_uint(scope_flags) - # MPY: n_obj - out.write_uint(0) - - # MPY: n_raw_code - out.write_uint(0) - - # MPY: rodata and/or bss + # MPY: bss and/or rodata if len(env.full_rodata): rodata_const_table_idx = 1 out.write_uint(len(env.full_rodata)) - out.write_bytes(env.full_rodata) if len(env.full_bss): - bss_const_table_idx = bool(env.full_rodata) + 1 + bss_const_table_idx = 2 out.write_uint(len(env.full_bss)) + if len(env.full_rodata): + out.write_bytes(env.full_rodata) # MPY: relocation information prev_kind = None @@ -969,10 +974,14 @@ def build_mpy(env, entry_offset, fmpy, native_qstr_vals, native_qstr_objs): kind = 0 elif isinstance(kind, str) and kind.startswith(".bss"): kind = bss_const_table_idx - elif kind == "mp_fun_table": + elif kind == "mp_native_qstr_table": kind = 6 + elif kind == "mp_native_obj_table": + kind = 7 + elif kind == "mp_fun_table": + kind = 8 else: - kind = 7 + kind + kind = 9 + kind assert addr % env.arch.word_size == 0, addr offset = addr // env.arch.word_size if kind == prev_kind and base == prev_base and offset == prev_offset + 1: @@ -1014,18 +1023,14 @@ def do_preprocess(args): for i, q in enumerate(static_qstrs): print("#define %s (%u)" % (q, i + 1), file=f) for i, q in enumerate(sorted(qstr_vals)): - print("#define %s (mp_native_qstr_val_table[%d])" % (q, i), file=f) + print("#define %s (mp_native_qstr_table[%d])" % (q, i + 1), file=f) for i, q in enumerate(sorted(qstr_objs)): print( - "#define MP_OBJ_NEW_QSTR_%s ((mp_obj_t)mp_native_qstr_obj_table[%d])" % (q, i), + "#define MP_OBJ_NEW_QSTR_%s ((mp_obj_t)mp_native_obj_table[%d])" % (q, i), file=f, ) - if args.arch == "xtensawin": - qstr_type = "uint32_t" # esp32 can only read 32-bit values from IRAM - else: - qstr_type = "uint16_t" - print("extern const {} mp_native_qstr_val_table[];".format(qstr_type), file=f) - print("extern const mp_uint_t mp_native_qstr_obj_table[];", file=f) + print("extern const uint16_t mp_native_qstr_table[];", file=f) + print("extern const mp_uint_t mp_native_obj_table[];", file=f) def do_link(args): diff --git a/tools/pyboard.py b/tools/pyboard.py index a43a4d0574857..a521a04a2ee27 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -472,7 +472,10 @@ def fs_cat(self, src, chunk_size=256): ) self.exec_(cmd, data_consumer=stdout_write_bytes) - def fs_get(self, src, dest, chunk_size=256): + def fs_get(self, src, dest, chunk_size=256, progress_callback=None): + if progress_callback: + src_size = int(self.exec_("import os\nprint(os.stat('%s')[6])" % src)) + written = 0 self.exec_("f=open('%s','rb')\nr=f.read" % src) with open(dest, "wb") as f: while True: @@ -488,9 +491,15 @@ def fs_get(self, src, dest, chunk_size=256): if not data: break f.write(data) + if progress_callback: + written += len(data) + progress_callback(written, src_size) self.exec_("f.close()") - def fs_put(self, src, dest, chunk_size=256): + def fs_put(self, src, dest, chunk_size=256, progress_callback=None): + if progress_callback: + src_size = os.path.getsize(src) + written = 0 self.exec_("f=open('%s','wb')\nw=f.write" % dest) with open(src, "rb") as f: while True: @@ -501,6 +510,9 @@ def fs_put(self, src, dest, chunk_size=256): self.exec_("w(b" + repr(data) + ")") else: self.exec_("w(" + repr(data) + ")") + if progress_callback: + written += len(data) + progress_callback(written, src_size) self.exec_("f.close()") def fs_mkdir(self, dir): @@ -527,7 +539,7 @@ def execfile(filename, device="/dev/ttyACM0", baudrate=115200, user="micro", pas pyb.close() -def filesystem_command(pyb, args): +def filesystem_command(pyb, args, progress_callback=None): def fname_remote(src): if src.startswith(":"): src = src[1:] @@ -560,7 +572,7 @@ def fname_cp_dest(src, dest): src = fname_remote(src) dest2 = fname_cp_dest(src, dest) print(fmt % (src, dest2)) - op(src, dest2) + op(src, dest2, progress_callback=progress_callback) else: op = { "ls": pyb.fs_ls, @@ -736,7 +748,7 @@ def execbuffer(buf): for filename in args.files: with open(filename, "rb") as f: pyfile = f.read() - if filename.endswith(".mpy") and pyfile[0] == ord("M"): + if filename.endswith(".mpy") and pyfile[0] == ord("C"): pyb.exec_("_injected_buf=" + repr(pyfile)) pyfile = _injected_import_hook_code execbuffer(pyfile) diff --git a/tools/uf2families.json b/tools/uf2families.json new file mode 100644 index 0000000000000..fafae82a60a44 --- /dev/null +++ b/tools/uf2families.json @@ -0,0 +1,192 @@ +[ + { + "id": "0x16573617", + "short_name": "ATMEGA32", + "description": "Microchip (Atmel) ATmega32" + }, + { + "id": "0x1851780a", + "short_name": "SAML21", + "description": "Microchip (Atmel) SAML21" + }, + { + "id": "0x1b57745f", + "short_name": "NRF52", + "description": "Nordic NRF52" + }, + { + "id": "0x1c5f21b0", + "short_name": "ESP32", + "description": "ESP32" + }, + { + "id": "0x1e1f432d", + "short_name": "STM32L1", + "description": "ST STM32L1xx" + }, + { + "id": "0x202e3a91", + "short_name": "STM32L0", + "description": "ST STM32L0xx" + }, + { + "id": "0x21460ff0", + "short_name": "STM32WL", + "description": "ST STM32WLxx" + }, + { + "id": "0x2abc77ec", + "short_name": "LPC55", + "description": "NXP LPC55xx" + }, + { + "id": "0x300f5633", + "short_name": "STM32G0", + "description": "ST STM32G0xx" + }, + { + "id": "0x31d228c6", + "short_name": "GD32F350", + "description": "GD32F350" + }, + { + "id": "0x04240bdf", + "short_name": "STM32L5", + "description": "ST STM32L5xx" + }, + { + "id": "0x4c71240a", + "short_name": "STM32G4", + "description": "ST STM32G4xx" + }, + { + "id": "0x4fb2d5bd", + "short_name": "MIMXRT10XX", + "description": "NXP i.MX RT10XX" + }, + { + "id": "0x53b80f00", + "short_name": "STM32F7", + "description": "ST STM32F7xx" + }, + { + "id": "0x55114460", + "short_name": "SAMD51", + "description": "Microchip (Atmel) SAMD51" + }, + { + "id": "0x57755a57", + "short_name": "STM32F4", + "description": "ST STM32F401" + }, + { + "id": "0x5a18069b", + "short_name": "FX2", + "description": "Cypress FX2" + }, + { + "id": "0x5d1a0a2e", + "short_name": "STM32F2", + "description": "ST STM32F2xx" + }, + { + "id": "0x5ee21072", + "short_name": "STM32F1", + "description": "ST STM32F103" + }, + { + "id": "0x621e937a", + "short_name": "NRF52833", + "description": "Nordic NRF52833" + }, + { + "id": "0x647824b6", + "short_name": "STM32F0", + "description": "ST STM32F0xx" + }, + { + "id": "0x68ed2b88", + "short_name": "SAMD21", + "description": "Microchip (Atmel) SAMD21" + }, + { + "id": "0x6b846188", + "short_name": "STM32F3", + "description": "ST STM32F3xx" + }, + { + "id": "0x6d0922fa", + "short_name": "STM32F407", + "description": "ST STM32F407" + }, + { + "id": "0x6db66082", + "short_name": "STM32H7", + "description": "ST STM32H7xx" + }, + { + "id": "0x70d16653", + "short_name": "STM32WB", + "description": "ST STM32WBxx" + }, + { + "id": "0x7eab61ed", + "short_name": "ESP8266", + "description": "ESP8266" + }, + { + "id": "0x7f83e793", + "short_name": "KL32L2", + "description": "NXP KL32L2x" + }, + { + "id": "0x8fb060fe", + "short_name": "STM32F407VG", + "description": "ST STM32F407VG" + }, + { + "id": "0xada52840", + "short_name": "NRF52840", + "description": "Nordic NRF52840" + }, + { + "id": "0xbfdd4eee", + "short_name": "ESP32S2", + "description": "ESP32-S2" + }, + { + "id": "0xc47e5767", + "short_name": "ESP32S3", + "description": "ESP32-S3" + }, + { + "id": "0xd42ba06c", + "short_name": "ESP32C3", + "description": "ESP32-C3" + }, + { + "id": "0x2b88d29c", + "short_name": "ESP32C2", + "description": "ESP32-C2" + }, + { + "id": "0x332726f6", + "short_name": "ESP32H2", + "description": "ESP32-H2" + }, + { + "id": "0xe48bff56", + "short_name": "RP2040", + "description": "Raspberry Pi RP2040" + }, + { + "id": "0x00ff6919", + "short_name": "STM32L4", + "description": "ST STM32L4xx" + }, + { + "id": "0x9af03e33", + "short_name": "GD32VF103", + "description": "GigaDevice GD32VF103" + } +] diff --git a/tools/uncrustify.cfg b/tools/uncrustify.cfg index a92530fd9316d..3812cd3182efa 100644 --- a/tools/uncrustify.cfg +++ b/tools/uncrustify.cfg @@ -372,7 +372,7 @@ sp_inside_square = ignore # ignore/add/remove/force sp_inside_square_oc_array = ignore # ignore/add/remove/force # Add or remove space after ',', i.e. 'a,b' vs. 'a, b'. -sp_after_comma = ignore # ignore/add/remove/force +sp_after_comma = add # ignore/add/remove/force # Add or remove space before ','. # diff --git a/tools/upip.py b/tools/upip.py index 70afe36a45c34..a62d04f66b89d 100644 --- a/tools/upip.py +++ b/tools/upip.py @@ -41,10 +41,6 @@ def op_split(path): return (head, r[1]) -def op_basename(path): - return op_split(path)[1] - - # Expects *file* name def _makedirs(name, mode=0o777): ret = False @@ -205,7 +201,6 @@ def install_pkg(pkg_spec, install_path): assert len(packages) == 1 package_url = packages[0]["url"] print("Installing %s %s from %s" % (pkg_spec, latest_ver, package_url)) - package_fname = op_basename(package_url) f1 = url_open(package_url) try: f2 = uzlib.DecompIO(f1, gzdict_sz) diff --git a/tools/verifygitlog.py b/tools/verifygitlog.py index 24171f9c68207..09c10c80d6082 100755 --- a/tools/verifygitlog.py +++ b/tools/verifygitlog.py @@ -69,7 +69,8 @@ def warning(err): # Message body lines. for line in raw_body[2:]: - if len(line) >= 76: + # Long lines with URLs are exempt from the line length rule. + if len(line) >= 76 and "://" not in line: error("Message lines should be 75 or less characters: " + line) if not raw_body[-1].startswith("Signed-off-by: ") or "@" not in raw_body[-1]: pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy