summaryrefslogtreecommitdiff
path: root/shared/runtime
AgeCommit message (Collapse)Author
2025-11-22shared/runtime/pyexec: Set PYEXEC_FORCED_EXIT flag for SystemExit.Andrew Leech
When `MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING` is enabled, `SystemExit` now sets the `PYEXEC_FORCED_EXIT` flag in addition to the exit code. This allows the REPL to properly detect and exit when SystemExit is raised, while still preserving the exit code in the lower bits. Fixes `repl_lock.py` test which expects REPL to exit on `SystemExit`. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
2025-11-22unix: Enable exit code handling for sys.exit().Andrew Leech
Enable `MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING` to propagate `sys.exit()` exit codes properly. Update `convert_pyexec_result()` to handle return values where pyexec returns the exit code with `PYEXEC_FORCED_EXIT` flag set for `SystemExit`. Extract the exit code from the lower 8 bits when the flag is set, otherwise return as-is (0 for success, 1 for exception). Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
2025-11-22shared/runtime/pyexec: Call mp_hal_stdio_mode_orig/raw as appropriate.Damien George
This ensures that ctrl-C works on the unix port when executing code at the REPL. Signed-off-by: Damien George <damien@micropython.org>
2025-11-22shared/runtime/pyexec: Provide support for compile-only mode.Andrew Leech
When `MICROPY_PYEXEC_COMPILE_ONLY` is enabled and the global `mp_compile_only` is True, code is compiled but not executed. Also add comprehensive tests for compile-only functionality covering both successful compilation and syntax error detection. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
2025-11-22shared/runtime/pyexec: Set __file__ for file input when enabled.Andrew Leech
When `MICROPY_MODULE___FILE__` is enabled and parsing file input, set the global `__file__` variable to the source filename. This matches the behavior of the unix port and provides the current filename to the executing script. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
2025-11-22unix/main: Use standard pyexec REPL for unix and windows ports.Andrew Leech
This improves REPL usage consistency across ports, by utilizing the pyexec code for the unix REPL. Only enabled when MICROPY_USE_READLINE == 1 (the default). Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
2025-11-04shared/runtime: Set exit code according to the SystemExit exception.John Smith
Add abort setup code `nlr_set_abort` to the standard runtime executor. This makes the standard runtime respond to abort signal without any further modifications. - When aborted, the program exits with 137 exit code (configurable, same as posix sig abort), to differentiate from a normal shutdown. - When exited by exception/crash, the program will exit with exit code 1 (configurable). - When exited by exception KeyboardInterrupt, the program will exit with exit code 130 (configurable, same as posix sig int). - When exited with a exit code (from Python environment), this code is propagated. When a different object is passed, exit code is set to 1 and the value printed, to be consistent with Python docs: https://python.readthedocs.io/en/latest/library/exceptions.html#SystemExit Signed-off-by: John Smith <jsmith@jsmith.cz>
2025-10-31shared/runtime/pyexec: Remove legacy USB IRQ enable code.Andrew Leech
It's very STM32 USB stack specific and doesn't generalise well to other ports. So remove it. Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
2025-09-25shared/runtime/mpirq: Check separate hard IRQ stack correctly.Chris Webb
On the zephyr port, hard IRQ handlers run with a separate stack on a different thread, so each call to mp_irq_dispatch() and mp_irq_handler() has to be wrapped with adjustments to the stack-limit checker. Move these adjustments into the shared mp_irq_dispatch(), introducing MICROPY_STACK_SIZE_HARD_IRQ which a port can define to non-zero if it uses a separate stack for hard IRQ handlers. We only need wrap the hard dispatch case. This should reduce binary size on zephyr without affecting other ports. Signed-off-by: Chris Webb <chris@arachsys.com>
2025-09-25shared/runtime/softtimer: Add support for hard callbacks.Chris Webb
Add a flag SOFT_TIMER_HARD_CALLBACK to request that a soft timer's python callback is run directly from the IRQ handler with the scheduler and heap locked, instead of being scheduled via mp_sched_schedule(). Signed-off-by: Chris Webb <chris@arachsys.com>
2025-09-25shared/runtime/mpirq: Factor out mp_irq_dispatch() and use it.Chris Webb
Separate out a routine to call an arbitrary function with arbitrary argument either directly as a hard-IRQ handler or scheduled as a soft-IRQ handler, adjusting mp_irq_handler() to wrap this. This can then be used to implement other hard/soft callbacks, such as for machine.Timer. Signed-off-by: Chris Webb <chris@arachsys.com>
2025-09-02shared/runtime/pyexec: Unconditionally reset lock depth.Jeff Epler
Saves code size for the same functionality. Signed-off-by: Jeff Epler <jepler@gmail.com>
2025-03-14shared/runtime/pyexec: Add helper function to execute a vstr.iabdalkader
Add `pyexec_vstr()` to execute Python code from a vstr source. Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2024-12-10shared/runtime/gchelper_generic: Fix AArch32 build on Clang.Alessandro Gatti
This commit fixes a compile error happening on Clang when building the generic gchelper code for AArch32. Clang would raise a warning regarding undefined variable access when aliasing a variable to an existing CPU register. The fix is pretty crude but it works - it simply disables the warning in question for the AArch32 gchelper collection function. Care was taken to make sure the code would also compile on GCC without warnings of sorts. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-10-03shared/runtime/gchelper_rv64i: Fix opcode sw/sd typo.Alessandro Gatti
The version of the assembly code for the GC helper that was committed ended up being a version that had an opcode typo in. The code was tested and working, but an undo operation too many when cleaning up the file before committing checked in the wrong version. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-09-06shared/runtime/sys_stdio_mphal: Fix printed type for stdio streams.timdechant
The printed type for stdio streams indicates "FileIO", which is a binary IO stream. Stdio is not binary by design, and its printed type should indicate a text stream. "TextIOWrapper" suits that purpose, and is used by VfsPosix files. Signed-off-by: timdechant <timdechant.git@gmail.com>
2024-08-28shared/runtime/semihosting_arm: Add mp_semihosting_exit.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2024-08-28shared/runtime/semihosting_arm: Add mp_semihosting_rx_chars.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2024-08-28shared/runtime/semihosting_arm: Support semihosting on non-Thumb ARM.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2024-08-07shared/runtime/gchelper: Add RISC-V RV64I native gchelper.Alessandro Gatti
Add native gchelper support for 64 bits RISC-V RV64I targets. Now that RV64 is under CI, this also enables platform-specific ghelper in the Unix port. Also changes the data type holding the register contents to something more appropriate, so in the remote eventuality somebody wants to use this with RV128 all they have to do is update the `__riscv_xlen` check. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-07-20shared/runtime/pyexec: Make a raised SystemExit always do a forced exit.Damien George
The current situation with SystemExit and soft reset is the following: - `sys.exit()` follows CPython and just raises `SystemExit`. - On the unix port, raising `SystemExit` quits the application/MicroPython, whether at the REPL or in code (this follows CPython behaviour). - On bare-metal ports, raising `SystemExit` at the REPL does nothing, raising it in code will stop the code and drop into the REPL. - `machine.soft_reset()` raises `SystemExit` but with a special flag set, and bare-metal targets check this flag when it propagates to the top-level and do a soft reset when they receive it. The original idea here was that a bare-metal target can't "quit" like the unix port can, and so dropping to the REPL was considered the same as "quit". But this bare-metal behaviour is arguably inconsistent with unix, and "quit" should mean terminate everything, including REPL access. This commit changes the behaviour to the following, which is more consistent: - Raising `SystemExit` on a bare-metal port will do a soft reset (unless the exception is caught by the application). - `machine.soft_reset()` is now equivalent to `sys.exit()`. - unix port behaviour remains unchanged. Tested running the test suite on an stm32 board and everything still passes, in particular tests that skip by raising `SystemExit` still correctly skip. Signed-off-by: Damien George <damien@micropython.org>
2024-06-06shared/runtime/semihosting: Add RISC-V semihosting support.Alessandro Gatti
This adds a RISC-V RV32 semihosting implementation, with all defined system calls exposed to the user. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-06-06shared/runtime/semihosting: Rename ARM semihosting files.Alessandro Gatti
Make room for RISC-V semihosting code, by renaming the existing `semihosting.[ch]` files into `semihosting_arm.[ch]`. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-06-06shared/runtime/gchelper: Add RISC-V RV32I native gchelper.Alessandro Gatti
Add native gchelper support for 32 bits RISC-V RV32I targets. Signed-off-by: Alessandro Gatti <a.gatti@frob.it>
2024-05-31rp2: Refactor to not use pico-sdk alarm pool functions for sleeping.Angus Gratton
The best_effort_wfe_or_timeout() and sleep_us() pico-sdk functions use the pico-sdk alarm pool internally, and that has a bug. Some usages inside pico-sdk (notably multicore_lockout_start_blocking()) will still end up calling best_effort_wfe_or_timeout(), although usually with "end_of_time" as the timeout value so it should avoid any alarm pool race conditions. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-05-31rp2: Refactor soft timer to use hardware timer alarm.Angus Gratton
Progress towards removing pico-sdk alarm pool, due to a known issue. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-03-07all: Remove the "STATIC" macro and just use "static" instead.Angus Gratton
The STATIC macro was introduced a very long time ago in commit d5df6cd44a433d6253a61cb0f987835fbc06b2de. The original reason for this was to have the option to define it to nothing so that all static functions become global functions and therefore visible to certain debug tools, so one could do function size comparison and other things. This STATIC feature is rarely (if ever) used. And with the use of LTO and heavy inline optimisation, analysing the size of individual functions when they are not static is not a good representation of the size of code when fully optimised. So the macro does not have much use and it's simpler to just remove it. Then you know exactly what it's doing. For example, newcomers don't have to learn what the STATIC macro is and why it exists. Reading the code is also less "loud" with a lowercase static. One other minor point in favour of removing it, is that it stops bugs with `STATIC inline`, which should always be `static inline`. Methodology for this commit was: 1) git ls-files | egrep '\.[ch]$' | \ xargs sed -Ei "s/(^| )STATIC($| )/\1static\2/" 2) Do some manual cleanup in the diff by searching for the word STATIC in comments and changing those back. 3) "git-grep STATIC docs/", manually fixed those cases. 4) "rg -t python STATIC", manually fixed codegen lines that used STATIC. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2024-02-16py/emitglue: Introduce mp_proto_fun_t as a more general mp_raw_code_t.Damien George
Allows bytecode itself to be used instead of an mp_raw_code_t in the simple and common cases of a bytecode function without any children. This can be used to further reduce frozen code size, and has the potential to optimise other areas like importing. Signed-off-by: Damien George <damien@micropython.org>
2023-12-22ports: Fix sys.stdout.buffer.write() return value.Maarten van der Schrieck
MicroPython code may rely on the return value of sys.stdout.buffer.write() to reflect the number of bytes actually written. While in most scenarios a write() operation is successful, there are cases where it fails, leading to data loss. This problem arises because, currently, write() merely returns the number of bytes it was supposed to write, without indication of failure. One scenario where write() might fail, is where USB is used and the receiving end doesn't read quickly enough to empty the receive buffer. In that case, write() on the MicroPython side can timeout, resulting in the loss of data without any indication, a behavior observed notably in communication between a Pi Pico as a client and a Linux host using the ACM driver. A complex issue arises with mp_hal_stdout_tx_strn() when it involves multiple outputs, such as USB, dupterm and hardware UART. The challenge is in handling cases where writing to one output is successful, but another fails, either fully or partially. This patch implements the following solution: mp_hal_stdout_tx_strn() attempts to write len bytes to all of the possible destinations for that data, and returns the minimum successful write length. The implementation of this is complicated by several factors: - multiple outputs may be enabled or disabled at compiled time - multiple outputs may be enabled or disabled at runtime - mp_os_dupterm_tx_strn() is one such output, optionally containing multiple additional outputs - each of these outputs may or may not be able to report success - each of these outputs may or may not be able to report partial writes As a result, there's no single strategy that fits all ports, necessitating unique logic for each instance of mp_hal_stdout_tx_strn(). Note that addressing sys.stdout.write() is more complex due to its data modification process ("cooked" output), and it remains unchanged in this patch. Developers who are concerned about accurate return values from write operations should use sys.stdout.buffer.write(). This patch might disrupt some existing code, but it's also expected to resolve issues, considering that the peculiar return value behavior of sys.stdout.buffer.write() is not well-documented and likely not widely known. Therefore, it's improbable that much existing code relies on the previous behavior. Signed-off-by: Maarten van der Schrieck <maarten@thingsconnected.nl>
2023-11-29shared/runtime/softtimer: Generalise soft_timer to work without SysTick.Damien George
If a port defines MICROPY_SOFT_TIMER_TICKS_MS then soft_timer assumes a SysTick back end, and provides a soft_timer_next variable that sets when the next call to soft_timer_handler() should occur. Otherwise, a port should provide soft_timer_get_ms() and soft_timer_schedule_at_ms() with appropriate semantics (see comments). Existing users of soft_timer should continue to work as they did. Signed-off-by: Damien George <damien@micropython.org>
2023-10-12py/builtinevex: Handle invalid filenames for execfile.Jim Mussared
If a non-string buffer was passed to execfile, then it would be passed as a non-null-terminated char* to mp_lexer_new_from_file. This changes mp_lexer_new_from_file to take a qstr instead (as in almost all cases a qstr will be created from this input anyway to set the `__file__` attribute on the module). This now makes execfile require a string (not generic buffer) argument, which is probably a good fix to make anyway. Fixes issue #12522. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2023-07-21py/stream: Add mp_stream___exit___obj that calls mp_stream_close.Jim Mussared
There are enough places that implement __exit__ by forwarding directly to mp_stream_close that this saves code size. For the cases where __exit__ is a no-op, additionally make their MP_STREAM_CLOSE ioctl handled as a no-op. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2023-04-27all: Fix spelling mistakes based on codespell check.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2023-04-05shared/runtime/pyexec: Don't allow Ctrl+C to interrupt frozen boot code.David Grayson
Helps prevent the filesystem from getting formatted by mistake, among other things. For example, on a Pico board, entering Ctrl+D and Ctrl+C fast many times will eventually wipe the filesystem (without warning or notice). Further rationale: Ctrl+C is used a lot by automation scripts (eg mpremote) and UI's (eg Mu, Thonny) to get the board into a known state. If the board is not responding for a short time then it's not possible to know if it's just a slow start up (eg in _boot.py), or an infinite loop in the main application. The former should not be interrupted, but the latter should. The only way to distinguish these two cases would be to wait "long enough", and if there's nothing on the serial after "long enough" then assume it's running the application and Ctrl+C should break out of it. But defining "long enough" is impossible for all the different boards and their possible behaviour. The solution in this commit is to make it so that frozen start-up code cannot be interrupted by Ctrl+C. That code then effectively acts like normal C start-up code, which also cannot be interrupted. Note: on the stm32 port this was never seen as an issue because all start-up code is in C. But now other ports start to put more things in _boot.py and so this problem crops up. Signed-off-by: David Grayson <davidegrayson@gmail.com>
2023-03-10py/gc: Make gc_dump_info/gc_dump_alloc_table take a printer as argument.Damien George
So that callers can redirect the output if needed. Signed-off-by: Damien George <damien@micropython.org>
2023-02-17shared/runtime/softtimer: Fix ticks range when computing ticks diff.Jim Mussared
The previous computation incorrectly assumed that the uint32_t ticks counter MICROPY_SOFT_TIMER_TICKS_MS was in the range [0,0x80000000) where its actually [0,0xffffffff]. This means the diff calculation can be simplified compared to the original implementation copied from utime_mphal.c, which has to deal with a ticks range constrained by the small int range. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2023-02-16shared/runtime/softtimer: Use consistently the same clock source.robert-hh
Before, both uwTick and mp_hal_ticks_ms() were used as clock source. That assumes, that these two are synchronous and start with the same value, which may be not the case for all ports. If the lag between uwTick and mp_hal_ticks_ms() is larger than the timer interval, the timer would either rush up until the times are synchronous, or not start until uwTick wraps over. As suggested by @dpgeorge, MICROPY_SOFT_TIMER_TICKS_MS is now used in softtimer.c, which has to be defined in a port's mpconfigport.h with the variable that holds the SysTick counter. Note that it's not possible to switch everything in softtimer.c to use mp_hal_ticks_ms() because the logic in SysTick_Handler that schedules soft_timer_handler() uses (eg on mimxrt) the uwTick variable directly (named systick_ms there), and mp_hal_ticks_ms() uses a different source timer. Thus it is made fully configurable.
2023-01-28shared/runtime/gchelper: Drop cpu directive from ARM asm helpers.David Lechner
This drops the `.cpu` directive from the ARM gchelper_*.s files. Having this directive breaks the linker when targeting older CPUs (e.g. `-mthumb -mthumb-interwork` for `-mcpu=arm7tdmi`). The actual target CPU should be determined by the compiler options. The exact CPU doesn't actually matter, but rather the supported assembly instruction set. So the files are renamed to *_thumb1.s and *thumb2.s to indicate the instruction set support instead of the CPU support. Signed-off-by: David Lechner <david@pybricks.com>
2023-01-24shared/runtime: Use mp_printf consistently, instead of printf.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-11-11shared/tinyusb: Further refactor static USB device implementation.Angus Gratton
App the mp_ prefix to usbd_ symbols and files which are defined here and not in TinyUSB. rp2 only for now. This includes some groundwork for dynamic USB devices (defined in Python). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
2022-11-08shared/runtime/gchelper_native: Fix pointer cast on x86_64.Simon Arlott
gc_helper_collect_regs_and_stack() is casting a pointer to uint32_t; the variables involved are always pointers so it should be using uintptr_t.
2022-09-19py/obj: Convert make_new into a mp_obj_type_t slot.Jim Mussared
Instead of being an explicit field, it's now a slot like all the other methods. This is a marginal code size improvement because most types have a make_new (100/138 on PYBV11), however it improves consistency in how types are declared, removing the special case for make_new. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2022-09-19py/obj: Merge getiter and iternext mp_obj_type_t slots.Jim Mussared
The goal here is to remove a slot (making way to turn make_new into a slot) as well as reduce code size by the ~40 references to mp_identity_getiter and mp_stream_unbuffered_iter. This introduces two new type flags: - MP_TYPE_FLAG_ITER_IS_ITERNEXT: This means that the "iter" slot in the type is "iternext", and should use the identity getiter. - MP_TYPE_FLAG_ITER_IS_CUSTOM: This means that the "iter" slot is a pointer to a mp_getiter_iternext_custom_t instance, which then defines both getiter and iternext. And a third flag that is the OR of both, MP_TYPE_FLAG_ITER_IS_STREAM: This means that the type should use the identity getiter, and mp_stream_unbuffered_iter as iternext. Finally, MP_TYPE_FLAG_ITER_IS_GETITER is defined as a no-op flag to give the default case where "iter" is "getiter". Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2022-09-19all: Remove unnecessary locals_dict cast.Jim Mussared
Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2022-09-19all: Make all mp_obj_type_t defs use MP_DEFINE_CONST_OBJ_TYPE.Jim Mussared
In preparation for upcoming rework of mp_obj_type_t layout. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2022-08-23shared/runtime/sys_stdio_mphal: Make func static and remove some TODOs.Damien George
stdio_obj_print is private to this file so can be made static. The __del__ method does nothing so can be removed (it's only called by the GC if it exists, so if it doesn't exist it won't be called). And FileIO doesn't support a constructor in MicroPython at this stage. Signed-off-by: Damien George <damien@micropython.org>
2022-07-19shared/runtime/softtimer: Remove obsolete #include statement.robert-hh
2022-07-19shared/runtime/softtimer: Move softtimer.[ch] to shared/runtime.robert-hh
And change the include lock to the naming scheme of that place. This comes from ports/stm32/softtimer.[ch].
2022-07-18shared/runtime/pyexec: Use MP_REGISTER_ROOT_POINTER().David Lechner
This uses MP_REGISTER_ROOT_POINTER() to register repl_line instead of using a conditional inside of mp_state_vm_t. Signed-off-by: David Lechner <david@pybricks.com>
2022-06-23shared/runtime/tinyusb_helpers: Add TinyUSB helper functions.iabdalkader
Currently this file only includes a CDC jump-to-bootloader helper function.