This adds support for the standard `weakref` module, to make weak
references to Python objects and have callbacks for when an object is
reclaimed by the GC.
This feature was requested by PyScript, to allow control over the lifetime
of external proxy objects (distinct from JS<->Python proxies).
Addresses issue #646 (that's nearly a 12 year old issue!).
Functionality added here:
- `weakref.ref(object [, callback])` create a simple weak reference with
optional callback to be called when the object is reclaimed by the GC
- `weakref.finalize(object, callback, /, *args, **kwargs)` create a
finalize object that holds a weak reference to an object and allows more
convenient callback usage and state change
The new module is enabled at the "everything" level.
The implementation aims to be as efficient as possible, by adding another
bit-per-block to the garbage collector, the WTB (weak table). Similar to
the finalizer bit (FTB), if a GC block has its corresponding WTB bit set
then a weak reference to that block is held. The details of that weak
reference are stored in a global map, `mp_weakref_map`, which maps weak
reference to ref/finalize objects, allowing the callbacks to be efficiently
found when the object is reclaimed.
With this feature enabled the overhead is:
- 1/128th of the available memory is used for the new WTB table (eg a 128k
heap now needs an extra 1k for the WTB).
- Code size is increased.
- At garbage collection time, there is a small overhead to check if the
collected objects had weak references. This check is the same as the
existing FTB finaliser scan, so shouldn't add much overhead. If there
are weak reference objects alive (ref/finalize objects) then additional
time is taken to call the callbacks and do some accounting to clean up
the used weak reference.
Signed-off-by: Damien George <damien@micropython.org>
This commit adds support for t-strings by leveraging the existing f-string
parser in the lexer. It includes:
- t-string parsing in `py/lexer.c`
- new built-in `__template__()` function to construct t-string objects
- new built-in `Template` and `Interpolation` classes which implement all
the functionality from PEP 750
- new built-in `string` module with `templatelib` sub-module, which
contains the classes `Template` and `Interpolation`
The way the t-string parser works is that an input t-string like:
t"hello {name:5}"
is converted character-by-character by the lexer/tokenizer to:
__template__(("hello ", "",), name, "name", None, "5")
For reference, if it were an f-string it would be converted to:
"hello {:5}".format(name)
Some properties of this implementation:
- it's enabled by default at the full feature level,
MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_FULL_FEATURES
- when enabled on a Cortex-M bare-metal port it costs about +3000 bytes
- there are no limits on the size or complexity of t-strings, and it allows
arbitrary levels of nesting of f-strings and t-strings (up to the memory
available to the compiler)
- the 'a' (ascii) conversion specifier is not supported (MicroPython does
not have the built-in `ascii` function)
- space after conversion specifier, eg t"{x!r :10}", is not supported
- arguments to `__template__` and `Interpolation` are not fully validated
(it's not necessary, it won't crash if the wrong arguments are passed in)
Otherwise the implementation here matches CPython.
Signed-off-by: Damien George <damien@micropython.org>
The `mp_obj_code_t` and `mp_type_code` code object was defined internally
in both `py/builtinevex.c` and `py/profile.c`, with completely different
implementations (the former very minimal, the latter quite complete).
This commit factors these implementations into a new, separate source file,
and allows the code object to have four different modes, selected at
compile-time:
- MICROPY_PY_BUILTINS_CODE_NONE: code object not included in the build.
- MICROPY_PY_BUILTINS_CODE_MINIMUM: very simple code object that just holds
a reference to the function that it represents. This level is used when
MICROPY_PY_BUILTINS_COMPILE is enabled.
- MICROPY_PY_BUILTINS_CODE_BASIC: simple code object that holds a reference
to the proto-function and its constants.
- MICROPY_PY_BUILTINS_CODE_FULL: almost complete implementation of the code
object. This level is used when MICROPY_PY_SYS_SETTRACE is enabled.
Signed-off-by: Damien George <damien@micropython.org>
This commit adds support for writing inline assembler functions when
targeting a RV32IMC processor.
Given that this takes up a bit of rodata space due to its large
instruction decoding table and its extensive error messages, it is
enabled by default only on offline targets such as mpy-cross and the
qemu port.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
This commit adds a new `RingIO` type which exposes the internal ring-buffer
code for general use in Python programs. It has the stream interface
making it similar to `StringIO` and `BytesIO`, except `RingIO` has a fixed
buffer size and is automatically safe when reads and writes are in
different threads or an IRQ.
This new type is enabled at the "extra features" ROM level.
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Currently the stack limit margin is hard-coded in each port's call to
`mp_stack_set_limit()`, but on threaded ports it's fiddlier and can lead to
bugs (such as incorrect thread stack margin on esp32).
This commit provides a new API to initialise the C Stack in one function
call, with a config macro to set the margin. Where possible the new call
is inlined to reduce code size in thread-free ports.
Intended replacement for `MP_TASK_STACK_LIMIT_MARGIN` on esp32.
The previous `stackctrl.h` API is still present and unmodified apart from a
deprecation comment. However it's not available when the
`MICROPY_PREVIEW_VERSION_2` macro is set.
This work was funded through GitHub Sponsors.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
This emitter prints out pseudo-machine instructions, instead of the usual
output of the native emitter. It can be enabled on any port via
`MICROPY_EMIT_NATIVE_DEBUG` (make sure other native emitters are disabled)
but the easiest way to use it is with mpy-cross:
$ mpy-cross -march=debug file.py
Signed-off-by: Damien George <damien@micropython.org>
This adds a native code generation backend for RISC-V RV32I CPUs, currently
limited to the I, M, and C instruction sets.
Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
Updates any includes, and references from Makefiles/CMake.
This essentially reverts what was done long ago in commit
136b5cbd76
This work was funded through GitHub Sponsors.
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This can be tested using ports/minimal and qemu:
make CC=mips-linux-gnu-gcc-8
Then run with qemu-mips:
stty raw opost -echo;
QEMU_LD_PREFIX=/usr/mips-linux-gnu/ qemu-mips build/firmware.elf;
sleep 1; reset
Signed-off-by: Jan Willeke <willeke@smartmote.de>