summaryrefslogtreecommitdiff
path: root/py
AgeCommit message (Collapse)Author
2022-04-14Revert "py/emitnative: Don't store prelude at end of machine code if..."Damien George
This reverts commit 7e8222ae063d78ae8f901bb0f9fef663edd2edb6. The prelude data must exist somewhere in the native code so load_raw_code and mpy-tool.py can access and parse it. Signed-off-by: Damien George <damien@micropython.org>
2022-04-14py/scheduler: Add support for scheduling static C-based callbacks.Damien George
If MICROPY_SCHEDULER_STATIC_NODES is enabled then C code can declare a static mp_sched_node_t and schedule a callback using mp_sched_schedule_node(). In contrast to using mp_sched_schedule(), the node version will have at most one pending callback outstanding, and will always be able to schedule if there is nothing already scheduled on this node. This guarantees that the the callback will be called exactly once after it is scheduled. Signed-off-by: Damien George <damien@micropython.org>
2022-04-11py/emitinlinethumb: Use 16 bit encodings for PUSH LR and POP PC.Christian Zietz
The Thumb instruction set has special 16 bit encodings for PUSH involving LR and POP involving PC, which are commonly used in nested functions. Using this encoding is particularly important for ARMv6-M, where the more general 32 bit encoding of PUSH and POP is unavailable.
2022-04-11extmod/modusocket: Provide config macro for socket.listen backlog deflt.Damien George
To make it possible to change this value for any given port or board. Signed-off-by: Damien George <damien@micropython.org>
2022-04-01py/makeqstrdefs: Cleanup and extend source file classification.Daniel Jour
- The classification of source files in makeqstrdefs.py has been moved into functions to consolidate the logic for that classification into a single place. - Classification of source files (into C or C++ or "other" files) is based on the filename extension. - For C++ there are many more common filename extensions than just ".cpp"; see "Options Controlling the Kind of Output" in man gcc for example. All common extensions for C++ source files which need preprocessing have been added.
2022-04-01py/runtime: Remove unnecessary check for kw_value == MP_OBJ_NULL.Damien George
The values are always real objects, only the key can be MP_OBJ_NULL to indicate a **kwargs entry. Signed-off-by: Damien George <damien@micropython.org>
2022-04-01py: Fix compiling and decoding of *args at large arg positions.Damien George
There were two issues with the existing code: 1. "1 << i" is computed as a 32-bit number so would overflow when executed on 64-bit machines (when mp_uint_t is 64-bit). This meant that *args beyond 32 positions would not be handled correctly. 2. star_args must fit as a positive small int so that it is encoded correctly in the emitted code. MP_SMALL_INT_BITS is too big because it overflows a small int by 1 bit. MP_SMALL_INT_BITS - 1 does not work because it produces a signed small int which is then sign extended when extracted (even by mp_obj_get_int_truncated), and this sign extension means that any position arg after *args is also treated as a star-arg. So the maximum bit position is MP_SMALL_INT_BITS - 2. This means that MP_OBJ_SMALL_INT_VALUE() can be used instead of mp_obj_get_int_truncated() to get the value of star_args. These issues are fixed by this commit, and a test added. Signed-off-by: Damien George <damien@micropython.org>
2022-03-31py/emitbc: Assert that a small int fits its encoding when emitting one.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-03-31py/runtime: Use size_t/ssize_t instead of uint/int.David Lechner
This replaces instances of uint with size_t and int with ssize_t in the mp_call_prepare_args_n_kw_var() function since all of the variables are used as array offsets. Also sort headers while we are touching this. Signed-off-by: David Lechner <david@pybricks.com>
2022-03-31py/runtime: Drop new_alloc < 4 check.David Lechner
To reach this check, n_kw has to be >= 1 and therefore args2_alloc has to be >= 2. Therefore new_alloc will always be >= 4. So this check will never be true and can be removed. Signed-off-by: David Lechner <david@pybricks.com>
2022-03-31py/runtime: Do not overallocate when len is known.David Lechner
This fixes overallocating an extra mp_obj_t when the length of *args and **args is known. Previously we were allocating 1 mp_obj_t for each n_args and n_kw plus the length of each *arg and **arg (if they are known). Since n_args includes *args and n_kw includes **args, this was allocating an extra mp_obj_t in addition to the length of these args when unpacked. To fix this, we just subtract 1 from the length to account for the 1 already implicitly allocated by n_args and n_kw. Signed-off-by: David Lechner <david@pybricks.com>
2022-03-31py/runtime: Allow multiple *args in a function call.David Lechner
This is a partial implementation of PEP 448 to allow unpacking multiple star args in a function or method call. This is implemented by changing the emitted bytecodes so that both positional args and star args are stored as positional args. A bitmap is added to indicate if an argument at a given position is a positional argument or a star arg. In the generated code, this new bitmap takes the place of the old star arg. It is stored as a small int, so this means only the first N arguments can be star args where N is the number of bits in a small int. The runtime is modified to interpret this new bytecode format while still trying to perform as few memory reallocations as possible. Signed-off-by: David Lechner <david@pybricks.com>
2022-03-31py/runtime: Allow multiple **args in a function call.David Lechner
This is a partial implementation of PEP 448 to allow multiple ** unpackings when calling a function or method. The compiler is modified to encode the argument as a None: obj key-value pair (similar to how regular keyword arguments are encoded as str: obj pairs). The extra object that was pushed on the stack to hold a single ** unpacking object is no longer used and is removed. The runtime is modified to decode this new format. Signed-off-by: David Lechner <david@pybricks.com>
2022-03-31py/vm: Prevent array bound warning when using -MP_OBJ_ITER_BUF_NSLOTS.Damien George
This warning can happen on clang 13.0.1 building mpy-cross: ../py/vm.c:748:25: error: array index -3 refers past the last possible element for an array in 64-bit address space containing 64-bit (8-byte) elements (max possible 2305843009213693952 elements) [-Werror,-Warray-bounds] sp[-MP_OBJ_ITER_BUF_NSLOTS + 1] = MP_OBJ_NULL; ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Using pointer access instead of array access works around this warning. Fixes issue #8467. Signed-off-by: Damien George <damien@micropython.org>
2022-03-30py/emitnative: Don't store prelude at end of machine code if not needed.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-03-30py/asmxtensa: Fix use of l32i/s32i when offset won't fit in encoding.Damien George
This commit adds optimised l32i/s32i functions that select the best load/ store encoding based on the size of the offset, and uses the function when necessary in code generation. Without this, ASM_LOAD_REG_REG_OFFSET() could overflow the word offset (using a narrow encoding), for example when loading the prelude from the constant table when there are many (>16) constants. Fixes issue #8458. Signed-off-by: Damien George <damien@micropython.org>
2022-03-30py/compile: Only show raw code that is bytecode.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-03-30py/bc.h: Fix C++20 compilation with "volatile".stijn
C++20 is deprecating several usages of the volatile keyword so remove this one affected case in the codebase which causes such warning.
2022-03-28py/builtinimport: Alias sys to usys if import weak links aren't enabled.Damien George
The sys module should always be available (if it's compiled in), eg to change sys.path for importing. So provide an explicit alias from "sys" to "usys" so that "import sys" can always work. Signed-off-by: Damien George <damien@micropython.org>
2022-03-28py: Change jump-if-x-or-pop opcodes to have unsigned offset argument.Damien George
These jumps are always forwards, and it's more efficient in the VM to decode an unsigned argument. These opcodes are already optimised versions of the sequence "dup-top pop-jump-if-x pop" so it doesn't hurt generality to optimise them further. Signed-off-by: Damien George <damien@micropython.org>
2022-03-28py/emitbc: Add check for bytecode jump offset overflow.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-03-28py: Change jump opcodes to emit 1-byte jump offset when possible.Damien George
This commit introduces changes: - All jump opcodes are changed to have variable length arguments, of either 1 or 2 bytes (previously they were fixed at 2 bytes). In most cases only 1 byte is needed to encode the short jump offset, saving bytecode size. - The bytecode emitter now selects 1 byte jump arguments when the jump offset is guaranteed to fit in 1 byte. This is achieved by checking if the code size changed during the last pass and, if it did (if it shrank), then requesting that the compiler make another pass to get the correct offsets of the now-smaller code. This can continue multiple times until the code stabilises. The code can only ever shrink so this iteration is guaranteed to complete. In most cases no extra passes are needed, the original 4 passes are enough to get it right by the 4th pass (because the 2nd pass computes roughly the correct labels and the 3rd pass computes the correct size for the jump argument). This change to the jump opcode encoding reduces .mpy files and RAM usage (when bytecode is in RAM) by about 2% on average. The performance of the VM is not impacted, at least within measurment of the performance benchmark suite. Code size is reduced for builds that include a decent amount of frozen bytecode. ARM Cortex-M builds without any frozen code increase by about 350 bytes. Signed-off-by: Damien George <damien@micropython.org>
2022-03-25py/objgenerator: Fix unused variables when native gen extracts prelude.Damien George
Some compilers will warn about unused variables like scope_flags. So use MP_BC_PRELUDE_SIG_DECODE() which will silence these warnings. Signed-off-by: Damien George <damien@micropython.org>
2022-03-25py/smallint: Introduce MP_SMALL_INT_BITS macro.David Lechner
This adds a new MP_SMALL_INT_BITS macro that is a compile-time constant that contains the number of bits available in an MP_SMALL_INT. We can use this in place of the runtime function mp_small_int_bits(). Signed-off-by: David Lechner <david@pybricks.com>
2022-03-16py/showbc: Remove global variables and make DECODE_PTR work correctly.Damien George
The bytecode state variables mp_showbc_code_start and mp_showbc_constants have been removed and made local variables passed into the various functions. As part of this, the DECODE_PTR macro is fixed so it extracts the relevant pointer from the child_table (a regression introduced in f2040bfc7ee033e48acef9f289790f3b4e6b74e5). Signed-off-by: Damien George <damien@micropython.org>
2022-03-16py/parse: Handle check for target small-int size in parser.Damien George
This means that all constants for EMIT_ARG(load_const_obj, obj) are created in the parser (rather than some in the compiler). Signed-off-by: Damien George <damien@micropython.org>
2022-03-16py/parse: Put const bytes objects in parse tree as const object.Damien George
Instead of as an intermediate qstr, which may unnecessarily intern the data of the bytes object. Signed-off-by: Damien George <damien@micropython.org>
2022-03-16py/parse: Simplify handling of const int parse nodes.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-03-10py/modsys: Add optional mutable attributes sys.ps1/ps2 and use them.Damien George
This allows customising the REPL prompt strings. Signed-off-by: Damien George <damien@micropython.org>
2022-03-10py/modsys: Add optional sys.tracebacklimit attribute.Damien George
With behaviour as per CPython. Signed-off-by: Damien George <damien@micropython.org>
2022-03-10py/modsys: Add optional attribute delegation.Damien George
To be enabled when needed by specific sys attributes. Signed-off-by: Damien George <damien@micropython.org>
2022-03-10py/objmodule: Support delegating failed attr lookups.Damien George
This commit adds generic support for mutable module attributes on built in modules, by adding support for an optional hook function for module attribute lookup. If a module wants to support additional attribute load/ store/delete (beyond what is in the constant, globals dict) then it should add at the very end of its globals dict MP_MODULE_ATTR_DELEGATION_ENTRY(). This should point to a custom function which will handle any additional attributes. The mp_module_generic_attr() function is provided as a helper function for additional attributes: it requires an array of qstrs (terminated in MP_QSTRnull) and a corresponding array of objects (with a 1-1 mapping between qstrs and objects). If the qstr is found in the array then the corresponding object is loaded/stored/deleted. Signed-off-by: Damien George <damien@micropython.org>
2022-03-10windows: Switch to VFS subsystem and use VfsPosix.Damien George
Following the unix port. Signed-off-by: Damien George <damien@micropython.org>
2022-03-09samd/moduos: Convert module to use extmod version.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-03-09extmod/moduos: Create general uos module to be used by all ports.Damien George
Based on the rp2 port version, with the rp2 port converted to use this module. Signed-off-by: Damien George <damien@micropython.org>
2022-03-01py/bc.h: Fix C++ compilation of public API.stijn
Casts between unrelated types must be explicit. Regression in f2040bfc7ee033e48acef9f289790f3b4e6b74e5
2022-02-24py: Rework bytecode and .mpy file format to be mostly static data.Damien George
Background: .mpy files are precompiled .py files, built using mpy-cross, that contain compiled bytecode functions (and can also contain machine code). The benefit of using an .mpy file over a .py file is that they are faster to import and take less memory when importing. They are also smaller on disk. But the real benefit of .mpy files comes when they are frozen into the firmware. This is done by loading the .mpy file during compilation of the firmware and turning it into a set of big C data structures (the job of mpy-tool.py), which are then compiled and downloaded into the ROM of a device. These C data structures can be executed in-place, ie directly from ROM. This makes importing even faster because there is very little to do, and also means such frozen modules take up much less RAM (because their bytecode stays in ROM). The downside of frozen code is that it requires recompiling and reflashing the entire firmware. This can be a big barrier to entry, slows down development time, and makes it harder to do OTA updates of frozen code (because the whole firmware must be updated). This commit attempts to solve this problem by providing a solution that sits between loading .mpy files into RAM and freezing them into the firmware. The .mpy file format has been reworked so that it consists of data and bytecode which is mostly static and ready to run in-place. If these new .mpy files are located in flash/ROM which is memory addressable, the .mpy file can be executed (mostly) in-place. With this approach there is still a small amount of unpacking and linking of the .mpy file that needs to be done when it's imported, but it's still much better than loading an .mpy from disk into RAM (although not as good as freezing .mpy files into the firmware). The main trick to make static .mpy files is to adjust the bytecode so any qstrs that it references now go through a lookup table to convert from local qstr number in the module to global qstr number in the firmware. That means the bytecode does not need linking/rewriting of qstrs when it's loaded. Instead only a small qstr table needs to be built (and put in RAM) at import time. This means the bytecode itself is static/constant and can be used directly if it's in addressable memory. Also the qstr string data in the .mpy file, and some constant object data, can be used directly. Note that the qstr table is global to the module (ie not per function). In more detail, in the VM what used to be (schematically): qst = DECODE_QSTR_VALUE; is now (schematically): idx = DECODE_QSTR_INDEX; qst = qstr_table[idx]; That allows the bytecode to be fixed at compile time and not need relinking/rewriting of the qstr values. Only qstr_table needs to be linked when the .mpy is loaded. Incidentally, this helps to reduce the size of bytecode because what used to be 2-byte qstr values in the bytecode are now (mostly) 1-byte indices. If the module uses the same qstr more than two times then the bytecode is smaller than before. The following changes are measured for this commit compared to the previous (the baseline): - average 7%-9% reduction in size of .mpy files - frozen code size is reduced by about 5%-7% - importing .py files uses about 5% less RAM in total - importing .mpy files uses about 4% less RAM in total - importing .py and .mpy files takes about the same time as before The qstr indirection in the bytecode has only a small impact on VM performance. For stm32 on PYBv1.0 the performance change of this commit is: diff of scores (higher is better) N=100 M=100 baseline -> this-commit diff diff% (error%) bm_chaos.py 371.07 -> 357.39 : -13.68 = -3.687% (+/-0.02%) bm_fannkuch.py 78.72 -> 77.49 : -1.23 = -1.563% (+/-0.01%) bm_fft.py 2591.73 -> 2539.28 : -52.45 = -2.024% (+/-0.00%) bm_float.py 6034.93 -> 5908.30 : -126.63 = -2.098% (+/-0.01%) bm_hexiom.py 48.96 -> 47.93 : -1.03 = -2.104% (+/-0.00%) bm_nqueens.py 4510.63 -> 4459.94 : -50.69 = -1.124% (+/-0.00%) bm_pidigits.py 650.28 -> 644.96 : -5.32 = -0.818% (+/-0.23%) core_import_mpy_multi.py 564.77 -> 581.49 : +16.72 = +2.960% (+/-0.01%) core_import_mpy_single.py 68.67 -> 67.16 : -1.51 = -2.199% (+/-0.01%) core_qstr.py 64.16 -> 64.12 : -0.04 = -0.062% (+/-0.00%) core_yield_from.py 362.58 -> 354.50 : -8.08 = -2.228% (+/-0.00%) misc_aes.py 429.69 -> 405.59 : -24.10 = -5.609% (+/-0.01%) misc_mandel.py 3485.13 -> 3416.51 : -68.62 = -1.969% (+/-0.00%) misc_pystone.py 2496.53 -> 2405.56 : -90.97 = -3.644% (+/-0.01%) misc_raytrace.py 381.47 -> 374.01 : -7.46 = -1.956% (+/-0.01%) viper_call0.py 576.73 -> 572.49 : -4.24 = -0.735% (+/-0.04%) viper_call1a.py 550.37 -> 546.21 : -4.16 = -0.756% (+/-0.09%) viper_call1b.py 438.23 -> 435.68 : -2.55 = -0.582% (+/-0.06%) viper_call1c.py 442.84 -> 440.04 : -2.80 = -0.632% (+/-0.08%) viper_call2a.py 536.31 -> 532.35 : -3.96 = -0.738% (+/-0.06%) viper_call2b.py 382.34 -> 377.07 : -5.27 = -1.378% (+/-0.03%) And for unix on x64: diff of scores (higher is better) N=2000 M=2000 baseline -> this-commit diff diff% (error%) bm_chaos.py 13594.20 -> 13073.84 : -520.36 = -3.828% (+/-5.44%) bm_fannkuch.py 60.63 -> 59.58 : -1.05 = -1.732% (+/-3.01%) bm_fft.py 112009.15 -> 111603.32 : -405.83 = -0.362% (+/-4.03%) bm_float.py 246202.55 -> 247923.81 : +1721.26 = +0.699% (+/-2.79%) bm_hexiom.py 615.65 -> 617.21 : +1.56 = +0.253% (+/-1.64%) bm_nqueens.py 215807.95 -> 215600.96 : -206.99 = -0.096% (+/-3.52%) bm_pidigits.py 8246.74 -> 8422.82 : +176.08 = +2.135% (+/-3.64%) misc_aes.py 16133.00 -> 16452.74 : +319.74 = +1.982% (+/-1.50%) misc_mandel.py 128146.69 -> 130796.43 : +2649.74 = +2.068% (+/-3.18%) misc_pystone.py 83811.49 -> 83124.85 : -686.64 = -0.819% (+/-1.03%) misc_raytrace.py 21688.02 -> 21385.10 : -302.92 = -1.397% (+/-3.20%) The code size change is (firmware with a lot of frozen code benefits the most): bare-arm: +396 +0.697% minimal x86: +1595 +0.979% [incl +32(data)] unix x64: +2408 +0.470% [incl +800(data)] unix nanbox: +1396 +0.309% [incl -96(data)] stm32: -1256 -0.318% PYBV10 cc3200: +288 +0.157% esp8266: -260 -0.037% GENERIC esp32: -216 -0.014% GENERIC[incl -1072(data)] nrf: +116 +0.067% pca10040 rp2: -664 -0.135% PICO samd: +844 +0.607% ADAFRUIT_ITSYBITSY_M4_EXPRESS As part of this change the .mpy file format version is bumped to version 6. And mpy-tool.py has been improved to provide a good visualisation of the contents of .mpy files. In summary: this commit changes the bytecode to use qstr indirection, and reworks the .mpy file format to be simpler and allow .mpy files to be executed in-place. Performance is not impacted too much. Eventually it will be possible to store such .mpy files in a linear, read-only, memory- mappable filesystem so they can be executed from flash/ROM. This will essentially be able to replace frozen code for most applications. Signed-off-by: Damien George <damien@micropython.org>
2022-02-17py/gc: Update debug code to compile with changes to qstr pool types.Damien George
Following on from 18b1ba086c0e5547ca81030bf13b026961f80720 and f46a7140f55a8f6d80f9c2d5f8db7af3de116794. Signed-off-by: Damien George <damien@micropython.org>
2022-02-11py/qstr: Use `const` consistently to avoid a cast.Artyom Skrobov
Originally at adafruit#4707 Signed-off-by: Artyom Skrobov <tyomitch@gmail.com>
2022-02-11py/qstr: Separate hash and len from string data.Artyom Skrobov
This allows the compiler to merge strings: e.g. "update", "difference_update" and "symmetric_difference_update" will all point to the same memory. No functional change. The size reduction depends on the number of qstrs in the build. The change this commit brings is: bare-arm: -4 -0.007% minimal x86: +150 +0.092% [incl +48(data)] unix x64: -608 -0.118% unix nanbox: -572 -0.126% [incl +32(data)] stm32: -1392 -0.352% PYBV10 cc3200: -448 -0.244% esp8266: -1208 -0.173% GENERIC esp32: -1028 -0.068% GENERIC[incl -1020(data)] nrf: -440 -0.252% pca10040 rp2: -1072 -0.217% PICO samd: -368 -0.264% ADAFRUIT_ITSYBITSY_M4_EXPRESS Performance is also improved (on bare metal at least) for the core_import_mpy_multi.py, core_import_mpy_single.py and core_qstr.py performance benchmarks. Originally at adafruit#4583 Signed-off-by: Artyom Skrobov <tyomitch@gmail.com>
2022-02-03ports: Consolidate inclusion of umachine module in built-ins.Damien George
The inclusion of `umachine` in the list of built-in modules is now done centrally in py/objmodule.c. Enabling MICROPY_PY_MACHINE will include this module. As part of this, all ports now have `umachine` as the core module name (previously some had only `machine` as the name). Signed-off-by: Damien George <damien@micropython.org>
2022-01-23py/modmath: Add math.tau, math.nan and math.inf constants.stijn
Configurable by the new MICROPY_PY_MATH_CONSTANTS option.
2022-01-23all: Fix MICROPY_OBJ_REPR_D compilation with msvc.stijn
2022-01-19py/objstr: Support '{:08}'.format("Jan") like Python 3.10.Jeff Epler
The new test has an .exp file, because it is not compatible with Python 3.9 and lower. See CPython version of the issue at https://bugs.python.org/issue27772 Signed-off-by: Jeff Epler <jepler@gmail.com>
2022-01-17all: Bump version to 1.18.v1.18Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-01-07py/mpconfig.h: Define MICROPY_PY_USSL_FINALISER only if not defined.Damien George
So a port can define it even if MICROPY_PY_USSL is not defined. Signed-off-by: Damien George <damien@micropython.org>
2022-01-07py/modbuiltins: Add additional macro for extending builtins.stijn
Mainly useful for defining additional globals in boards and variants.
2022-01-06py/qstr: Reset mpstate.qstr_last_chunk before raising an error.Emilie Feral
The qstr_last_chunk is not collected by the garbage collector. This relies on the assertion that qstr_pool_t also references the qstr_last_chunk. If an exception is raised while allocating the qstr_pool_t, qstr_last_chunk has to be invalidated not to become a dangling reference at the next garbage collection. Signed-off-by: Emilie Feral <emilie.feral@numworks.com>
2021-12-29ports: Move '.frozen' to second entry in sys.path.Damien George
In commit 86ce4426079b1b368881c22f46d80045e2f720b0 the '.frozen' entry was added at the start of sys.path, to allow control over when frozen modules are searched during import, and retain existing behaviour whereby frozen was searched before the filesystem. But Python semantics of sys.path require sys.path[0] to be the directory of the currently executing script, or ''. This commit moves the '.frozen' entry to second place in sys.path, so sys.path[0] retains its correct value (described above). Signed-off-by: Damien George <damien@micropython.org>
2021-12-21py/mpz: Fix bugs with bitwise of -0 by ensuring all 0's are positive.Damien George
This commit makes sure that the value zero is always encoded in an mpz_t as neg=0 and len=0 (previously it was just len=0). This invariant is needed for some of the bitwise operations that operate on negative numbers, because they cannot handle -0. For example (-((1<<100)-(1<<100)))|1 was being computed as -65535, instead of 1. Fixes issue #8042. Signed-off-by: Damien George <damien@micropython.org>