Age | Commit message (Collapse) | Author |
|
Following discussions in PR #16666, this commit updates the float
formatting code to improve the `repr` reversibility, i.e. the percentage of
valid floating point numbers that do parse back to the same number when
formatted by `repr` (in CPython it's 100%).
This new code offers a choice of 3 float conversion methods, depending on
the desired tradeoff between code size and conversion precision:
- BASIC method is the smallest code footprint
- APPROX method uses an iterative method to approximate the exact
representation, which is a bit slower but but does not have a big impact
on code size. It provides `repr` reversibility on >99.8% of the cases in
double precision, and on >98.5% in single precision (except with REPR_C,
where reversibility is 100% as the last two bits are not taken into
account).
- EXACT method uses higher-precision floats during conversion, which
provides perfect results but has a higher impact on code size. It is
faster than APPROX method, and faster than the CPython equivalent
implementation. It is however not available on all compilers when using
FLOAT_IMPL_DOUBLE.
Here is the table comparing the impact of the three conversion methods on
code footprint on PYBV10 (using single-precision floats) and reversibility
rate for both single-precision and double-precision floats. The table
includes current situation as a baseline for the comparison:
PYBV10 REPR_C FLOAT DOUBLE
current = 364688 12.9% 27.6% 37.9%
basic = 364812 85.6% 60.5% 85.7%
approx = 365080 100.0% 98.5% 99.8%
exact = 366408 100.0% 100.0% 100.0%
Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
|
|
This commit extracts from the current float parsing code two functions
which could be reused elsewhere in MicroPython.
The code used to multiply a float x by a power of 10 is also simplified by
applying the binary exponent separately from the power of 5. This avoids
the risk of overflow in the intermediate stage, before multiplying by x.
Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
|
|
This reduces memory use by reusing objects, and improves identity/equality
relationships of JavaScript objects on the Python side.
In 77bd8fe5b80b0e7e02cdb6b4272c401ae3dca638 PyProxy's were reused when the
same Python object was proxied across to JavaScript. This commit does the
same thing but for JsProxy's going from JS to Python. If an existing
JsProxy reference exists for the JS object about to be proxied across, then
it's reused.
This helps reduce the number of alive objects (memory use), and, more
importantly, improves equality relationships of JavaScript objects on the
Python side. Eg we now get, on the Python side:
import js
print(js.Object == js.Object)
that prints True. Previously it was False.
Note that this change does not make identity work with `is`, for example
`js.Object is js.Object` is actually False. With more work that could be
made True but for now we leave that as-is.
The behaviour with this commit matches Pyodide semantics.
Signed-off-by: Damien George <damien@micropython.org>
|
|
Signed-off-by: Damien George <damien@micropython.org>
|
|
This option is needed for ports such as webassembly where objects are
proxied and can be identical without being the same C pointer.
Signed-off-by: Damien George <damien@micropython.org>
|
|
It's possible for a test to output non-ASCII characters (for example, due
to a hard fault or serial noise or memory corruption). Rather than crashing
the test runner, backslash escape those characters and treat them as
program output.
Refactors the string encoding step to a single helper to avoid copy-paste.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
|
|
As per comment, if a boot.py is present that connects to Wi-Fi then waking
can take a little longer.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
|
|
This follows a similar change made for `run-tests.py` in commit
229104558fb7f9d283b7302bc3720bc35c5c49cf. The change here uses the same
logic to detect if a natmod test is too big for the target (eg overflows
(I)RAM loading the native .mpy), by printing "START TEST" at the start of
the test.
Typical output is now something like this:
...
pass extmod/random_basic.py
pass extmod/random_extra_float.py
pass extmod/random_extra.py
SKIP extmod/random_seed_default.py
LRGE extmod/re1.py
SKIP extmod/re_debug.py
pass extmod/re_error.py
pass extmod/re_group.py
pass extmod/re_groups.py
...
and the tests that are too large are reported at the end, and written to
the `_result.json` file.
Signed-off-by: Damien George <damien@micropython.org>
|
|
The UUID32 case was incorrect: first, the "<d" should have been "<I", and
second, the UUID constructor treats integer arguments as UUID16. So this
UUID32 case needs to pass in the actual data bytes.
And then it's simpler to just make all cases pass in the data bytes.
Signed-off-by: Damien George <damien@micropython.org>
|
|
Signed-off-by: Damien George <damien@micropython.org>
|
|
This commit adjusts the configuration of the standard zephyr build to use
MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES. That's a lot cleaner than
explicitly enabling/disabling options, and allows boards to more easily
fine-tune the settings, eg select a different feature level.
Features that are now enabled are:
- async/await keyword support
- `filter`, `property` and `reversed` builtins
- `range` attributes
- `str.count()` method
- `array` module with `array.array` object
- `collections` module with `collections.namedtuple` object
- `struct` module with everything
- `id = const()` and constant folding in the compiler
Bulding qemu_cortex_m3, the code size was originally:
Memory region Used Size Region Size %age Used
FLASH: 193864 B 256 KB 73.95%
RAM: 61992 B 64 KB 94.59%
and with this commit it is now:
Memory region Used Size Region Size %age Used
FLASH: 200698 B 256 KB 76.56%
RAM: 61992 B 64 KB 94.59%
That's a mild increase of +6834 bytes flash usage for a good selection of
new features.
Signed-off-by: Damien George <damien@micropython.org>
|
|
This commit adjusts the configuration of the minimal zephyr build to use
MICROPY_CONFIG_ROM_LEVEL_MINIMUM. That's a lot cleaner than explicitly
enabling/disabling options.
Prior to this change the minimal build for qemu_cortex_m3 had size:
Memory region Used Size Region Size %age Used
FLASH: 114436 B 256 KB 43.65%
RAM: 26320 B 64 KB 40.16%
and had the following test results (running using the CI settings, ie
`-d basics float --exclude inf_nan_arith`):
352 tests performed (7092 individual testcases)
352 tests passed
254 tests skipped: ...
With the changes here the qemu_cortex_m3 size is now:
Memory region Used Size Region Size %age Used
FLASH: 99428 B 256 KB 37.93%
RAM: 26312 B 64 KB 40.15%
That's a good decrease of about 15k firmware size. And the test suite
still passes with:
342 tests performed (6776 individual testcases)
341 tests passed
265 tests skipped: ...
Signed-off-by: Damien George <damien@micropython.org>
|
|
Contrary to the docs, mbedtls can return more than just
MBEDTLS_ERR_SSL_ALLOC_FAILED when `mbedtls_ssl_setup()` fails. At least
MBEDTLS_ERR_MD_ALLOC_FAILED was also seen on ESP32_GENERIC, but there
could possibly be other error codes.
To cover all these codes, just check if `ret` is non-0, and in that case
do a `gc_collect()` and retry the init.
Signed-off-by: Damien George <damien@micropython.org>
|
|
This includes "stddef.h" for `size_t` to resolve NuttX integration build
issues.
Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
|
|
ESP32-C2 ROM prints at 74880bps (same as ESP8266), so need a newline
before first MicroPython output to avoid it being appended on end of
a line of noise.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
|
|
This is necessary for ESP32-C2 Wi-Fi & BT to work reliably (and for TLS to
work at all). On IDF 5.4.2 the free static RAM goes from 60KB to 100KB, and
there will also be a reduction in lwIP & Wi-Fi memory use at runtime.
The performance trade-off seems low for most use cases, although it will
probably be significant for certain combinations of load (i.e. heavy
TCP/IP, heavy BT throughput, and some peripheral driver functions).
Added as a set of config flags because this is potentially useful on other
SoCs where the goal is to maximise RAM available for MicroPython.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
|
|
Includes:
esp32/esp32c2: Adapt to target chip ESP32C2.
esp32/esp32c2: Fix heap size is too small to enable Bluetooth.
Signed-off-by: TianShuangKe <qinyun575@gmail.com>
Signed-off-by: Angus Gratton <angus@redyak.com.au>
|
|
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
|
|
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
|
|
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
|
|
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
|
|
This commit adds support for the `__set_name__` data model method specified
by PEP487 - Simpler customisation of class creation.
This includes support for methods that mutate the owner class, and avoids
the naive modify-while-iterating hazard possible in a naive implementation
like micropython/micropython#15503.
Note that based on the benchmarks in micropython/micropython#16825, this is
also as fast or faster than the naive implementation, thanks to clever data
layout in `setname_list_t`, and the way this allows the capture step to run
during an existing loop through the class dict.
Other rejected approaches for dealing with the hazard include:
- python/cpython#72983
During the implementation of this feature for MicroPython, it was
discovered that some versions of CPython also have this naive hazard.
CPython resolved this bug in BPO-28797 and now makes a complete flat copy
of the class's dict to iterate. This design decision doesn't make much
sense for a microcontroller though, even if it's perfectly reasonable in
the desktop world where memcpy might actually be cheaper than a
hard-to-branch-predict conditional; and it's also motivated in their case
by error-tracing considerations.
- micropython/micropython#16816
This is an equivalent implementation to CPython's approach that places this
copy directly on the stack; however it is both slower and has larger code
size than the approach taken here.
- micropython/micropython#15503
The simplest implementation is to just not worry about it and let the user
face the consequences if they mutate the owner class. That's not a very
friendly behavior, though, and it's not actually much more performant than
this implementation on either time or code size.
- micropython/micropython#17693
Another alternative is to do the same as #15503 but leverage MicroPython's
existing `is_fixed` field in its dict type to convert attempted mutations
of the owner dict into `AttributeError`s. This is safer than just leaving
the open hazard, but there's still important use-cases for owner-mutating
descriptors, and the performance gain is small enough that it isn't worth
missing support for those cases.
- combined micropython/micropython#17693 with this
Another version of this feature used a new feature define,
`MICROPY_PY_METACLASSES_LITE`, to control whether this algorithm or the
naive version is used. This was rejected in favor of simplicity, based on
the very limited performance margin the naive version has (which in some
cases even goes _against_ it).
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
|
|
Including the stochastic tests needed to guarantee sensitivity to the
potential iterate-while-modifying hazard a naive implementation might have.
Signed-off-by: Anson Mansfield <amansfield@mantaro.com>
|
|
Current longlong implementation does not allow a float as RHS of mathematic
operators, as it lacks the delegation code present in mpz.
Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
|
|
This is to fix an outstanding TODO. The test cases is using a range as
this will exist in all builds, but `mp_obj_get_int` is used in many
different parts of code where an overflow is more likely to occur.
Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
|
|
This finding is based on fuzzing MicroPython. I manually minimized the
test case it provided.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
XOSC_MHZ and XOSC_KHZ may not be defined if we use a custom XIN clock
by defining PLL_SYS_REFDIV etc. calculated by vcocalc.py.
Signed-off-by: Christian Lang <lang.chr86@gmail.com>
|
|
On a build like nanbox, `mp_uint_t` is wider than `u/intptr_t`. Using a
signed type for fetching pointer values resulted in erroneous results: like
`<function f at 0xfffffffff7a60bc0>` instead of
`<function f at 0xf7a60bc0>`.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
All these arguments are of type `mp_{u,}int_t`, but the actual value is
always a small integer. Cast it so that it can format with the `%d/%u`
formatter.
Before, the compiler plugin produced an error in the PYBD_SF6 build, which
is a nanboxing build with 64-bit ints.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
On the nanbox build, `o->obj` is a 64-bit type but `%p` formats a 32-bit
type, leading to undefined behavior.
Print the cell's ID as a hex integer instead.
This location was found using an experimental gcc plugin for `mp_printf`
error checking.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
Before, the compiler plugin produced an error in the PYBD_SF6 build, which
is a nanboxing build with 64-bit ints.
I made the decision here to cast the value even though some significant
bits might be lost after 49.7 days. However, the format used is "% 8d",
which produces a consistent width output for small ticks values (up to
about 1.1 days). I judged that it was more valuable to preserve the fixed
width display than to accurately represent long time periods.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
As timeout is of type `mp_uint_t`, it must be printed with UINT_FMT.
Before, the compiler plugin produced an error in the PYBD_SF6 build, which
is a nanboxing build with 64-bit ints.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
These locations were found using an experimental gcc plugin for `mp_printf`
error checking.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
During the coverage test, all the values encountered are within the range
of `%d`.
These locations were found using an experimental gcc plugin for `mp_printf`
error checking.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
This fixes the following diagnostic produced by the plugin:
error: argument 3: Format ‘%x’ requires a ‘int’ or
‘unsigned int’ (32 bits), not ‘long unsigned int’ [size 64]
[-Werror=format=]
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
We still want this not to crash a runtime but the new static checker
wouldn't like it.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
The type of the argument must match the format string. Add casts to ensure
that they do.
It's possible that casting from `size_t` to `unsigned` loses the correct
values by masking off upper bits, but it seems likely that the quantities
involved in practice are small enough that the `%u` formatter (32 bits on
most platforms, 16 on pic16bit) will in fact hold the correct value.
The alternative, casting to a wider type, adds code size.
These locations were found using an experimental gcc plugin for `mp_printf`
error checking, cross-building for x64 windows on Linux.
In one case there was already a cast, but it was written incorrectly and
did not have the intended effect.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
The name field of type objects is of type `uint16_t` for efficiency, but
when the type is passed to `mp_printf` it must be cast explicitly to type
`qstr`.
These locations were found using an experimental gcc plugin for `mp_printf`
error checking, cross-building for x64 windows on Linux.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
The default definition in `py/mpconfig.h` for 32-bit architectures is
`%u/%d`, so these can be removed.
Signed-off-by: Jeff Epler <jepler@gmail.com>
|
|
These tests all depend on generating arbitrarily long (>64-bit) integers.
It would be possible to have these tests work in this case I think, as the
results are always masked to shorter values. But quite fiddly. So just
rename them so they are automatically skipped if the target doesn't have
big int support.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
|
|
Previous comment was wrong, left shifting a negative value is UB in C. Use
the same approach as small int shifts (from runtime.c).
Signed-off-by: Angus Gratton <angus@redyak.com.au>
|
|
The recently merged 5e9189d6d1c00c92694888bf9c74276779c40716 now allows
temporary slices to be allocated on the C stack, which is much better than
allocating them on the GC heap.
Unfortunately there are cases where the C-allocated slice can escape and be
retained as an object, which leads to crashes (because that object points
to the C stack which now has other values on it).
The fix here is to add a new `MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE`.
Native types should set this flag if their subscr method is guaranteed not
to hold on to a reference of the slice object.
Fixes issue #17733 (see also #17723).
Signed-off-by: Damien George <damien@micropython.org>
|
|
Fixes a bug in the binding of self/this to JavaScript methods.
The new semantics match Pyodide's behaviour, at least for the included
tests.
Signed-off-by: Damien George <damien@micropython.org>
|
|
Signed-off-by: Damien George <damien@micropython.org>
|
|
And run both armv6m and armv7m under qemu.
Signed-off-by: Damien George <damien@micropython.org>
|
|
Signed-off-by: Damien George <damien@micropython.org>
|