summaryrefslogtreecommitdiff
path: root/py/persistentcode.c
AgeCommit message (Collapse)Author
2022-07-18py/persistentcode: Use MP_REGISTER_ROOT_POINTER().David Lechner
This uses MP_REGISTER_ROOT_POINTER() to register track_reloc_code_list instead of using a conditional inside of mp_state_vm_t. Signed-off-by: David Lechner <david@pybricks.com>
2022-06-23py/parsenum: Optimise when building with complex disabled.Damien George
To reduce code size when MICROPY_PY_BUILTINS_COMPLEX is disabled. Signed-off-by: Damien George <damien@micropython.org>
2022-06-07py/persistentcode: Remove remaining native qstr linking support.Damien George
Support for architecture-specific qstr linking was removed in d4d53e9e114d779523e382c4ea38f0398e880aae, where native code was changed to access qstr values via qstr_table. The only remaining use for the special qstr link table in persistentcode.c is to support native module written in C, linked via mpy_ld.py. But native modules can also use the standard module-level qstr_table (and obj_table) which was introduced in the .mpy file reworking in f2040bfc7ee033e48acef9f289790f3b4e6b74e5. This commit removes the remaining native qstr liking support in persistentcode.c's load_raw_code function, and adds two new relocation options for constants.qstr_table and constants.obj_table. mpy_ld.py is updated to use these relocations options instead of the native qstr link table. Signed-off-by: Damien George <damien@micropython.org>
2022-05-23py/emitnative: Access qstr values using indirection table qstr_table.Damien George
This changes the native emitter to access qstr values using the qstr indirection table qstr_table, but only when generating native code that will be saved to a .mpy file. This makes the resulting native code fully static, ie it does not require any fix-ups or rewriting when it is imported. The performance of native code is more or less unchanged. Benchmark results on PYBv1.0 (using --via-mpy and --emit native) are: N=100 M=100 baseline -> this-commit diff diff% (error%) bm_chaos.py 407.16 -> 411.85 : +4.69 = +1.152% (+/-0.01%) bm_fannkuch.py 100.89 -> 101.20 : +0.31 = +0.307% (+/-0.01%) bm_fft.py 3521.17 -> 3441.72 : -79.45 = -2.256% (+/-0.00%) bm_float.py 6707.29 -> 6644.83 : -62.46 = -0.931% (+/-0.00%) bm_hexiom.py 55.91 -> 55.41 : -0.50 = -0.894% (+/-0.00%) bm_nqueens.py 5343.54 -> 5326.17 : -17.37 = -0.325% (+/-0.00%) bm_pidigits.py 603.89 -> 632.79 : +28.90 = +4.786% (+/-0.33%) core_qstr.py 64.18 -> 64.09 : -0.09 = -0.140% (+/-0.01%) core_yield_from.py 313.61 -> 311.11 : -2.50 = -0.797% (+/-0.03%) misc_aes.py 654.29 -> 659.75 : +5.46 = +0.834% (+/-0.02%) misc_mandel.py 4205.10 -> 4272.08 : +66.98 = +1.593% (+/-0.01%) misc_pystone.py 3077.79 -> 3128.39 : +50.60 = +1.644% (+/-0.01%) misc_raytrace.py 388.45 -> 393.71 : +5.26 = +1.354% (+/-0.01%) viper_call0.py 576.83 -> 566.76 : -10.07 = -1.746% (+/-0.05%) viper_call1a.py 550.39 -> 540.12 : -10.27 = -1.866% (+/-0.11%) viper_call1b.py 438.32 -> 432.09 : -6.23 = -1.421% (+/-0.11%) viper_call1c.py 442.96 -> 436.11 : -6.85 = -1.546% (+/-0.08%) viper_call2a.py 536.31 -> 527.37 : -8.94 = -1.667% (+/-0.04%) viper_call2b.py 378.99 -> 377.50 : -1.49 = -0.393% (+/-0.08%) Signed-off-by: Damien George <damien@micropython.org>
2022-05-17py/emitnative: Put a pointer to the native prelude in child_table array.Damien George
Some architectures (like esp32 xtensa) cannot read byte-wise from executable memory. This means the prelude for native functions -- which is usually located after the machine code for the native function -- must be placed in separate memory that can be read byte-wise. Prior to this commit this was achieved by enabling N_PRELUDE_AS_BYTES_OBJ for the emitter and MICROPY_EMIT_NATIVE_PRELUDE_AS_BYTES_OBJ for the runtime. The prelude was then placed in a bytes object, pointed to by the module's constant table. This behaviour is changed by this commit so that a pointer to the prelude is stored either in mp_obj_fun_bc_t.child_table, or in mp_obj_fun_bc_t.child_table[num_children] if num_children > 0. The reasons for doing this are: 1. It decouples the native emitter from runtime requirements, the emitted code no longer needs to know if the system it runs on can/can't read byte-wise from executable memory. 2. It makes all ports have the same emitter behaviour, there is no longer the N_PRELUDE_AS_BYTES_OBJ option. 3. The module's constant table is now used only for actual constants in the Python code. This allows further optimisations to be done with the constants (eg constant deduplication). Code size change for those ports that enable the native emitter: unix x64: +80 +0.015% stm32: +24 +0.004% PYBV10 esp8266: +88 +0.013% GENERIC esp32: -20 -0.002% GENERIC[incl -112(data)] rp2: +32 +0.005% PICO Signed-off-by: Damien George <damien@micropython.org>
2022-05-17py/persistentcode: Remove obsolete comment about qstr window size.Damien George
This was made obsolete in f2040bfc7ee033e48acef9f289790f3b4e6b74e5 Signed-off-by: Damien George <damien@micropython.org>
2022-04-14py/persistentcode: Support loading and saving tuples in .mpy files.Damien George
Signed-off-by: Damien George <damien@micropython.org>
2022-04-14py/persistentcode: Define enum values for obj types instead of letters.Damien George
To keep the separate parts of the code that use these values in sync. And make it easier to add new object types. 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/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-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>
2021-02-04all: Rename BYTES_PER_WORD to MP_BYTES_PER_OBJ_WORD.Damien George
The "word" referred to by BYTES_PER_WORD is actually the size of mp_obj_t which is not always the same as the size of a pointer on the target architecture. So rename this config value to better reflect what it measures, and also prefix it with MP_. For uses of BYTES_PER_WORD in setting the stack limit this has been changed to sizeof(void *), because the stack usually grows with machine-word sized values (eg an nlr_buf_t has many machine words in it). Signed-off-by: Damien George <damien@micropython.org>
2021-01-30py/persistentcode: Introduce MICROPY_PERSISTENT_CODE_SAVE_FILE option.David CARLIER
This should be enabled when the mp_raw_code_save_file function is needed. It is enabled for mpy-cross, and a check for defined(__APPLE__) is added to cover Mac M1 systems.
2020-08-02py/persistentcode: Maintain root ptr list of imported native .mpy code.Damien George
On ports where normal heap memory can contain executable code (eg ARM-based ports such as stm32), native code loaded from an .mpy file may be reclaimed by the GC because there's no reference to the very start of the native machine code block that is reachable from root pointers (only pointers to internal parts of the machine code block are reachable, but that doesn't help the GC find the memory). This commit fixes this issue by maintaining an explicit list of root pointers pointing to native code that is loaded from an .mpy file. This is not needed for all ports so is selectable by the new configuration option MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE. It's enabled by default if a port does not specify any special functions to allocate or commit executable memory. A test is included to test that native code loaded from an .mpy file does not get reclaimed by the GC. Fixes #6045. Signed-off-by: Damien George <damien@micropython.org>
2020-04-05all: Use MP_ERROR_TEXT for all error messages.Jim Mussared
2020-02-28all: Reformat C and Python source code with tools/codeformat.py.Damien George
This is run with uncrustify 0.70.1, and black 19.10b0.
2020-01-26py: Release GIL during syscalls in reader and writer code.David Lechner
This releases the GIL during POSIX system calls that could block.
2019-12-17py/persistentcode: Move loading of rodata/bss to before obj/raw-code.Damien George
This makes the loading of viper-code-with-relocations a bit neater and easier to understand, by treating the rodata/bss like a special object to be loaded into the constant table (which is how it behaves).
2019-12-12py/persistentcode: Make ARM Thumb archs support multiple sub-archs.Damien George
2019-12-12py/nativeglue: Add new header file with native function table typedef.Damien George
2019-12-12py/persistentcode: Add ability to relocate loaded native code.Damien George
Implements text, rodata and bss generalised relocations, as well as generic qstr-object linking. This allows importing dynamic native modules on all supported architectures in a unified way.
2019-11-04py/persistentcode: Move declarations for .mpy header from .c to .h file.Damien George
2019-10-15py/persistentcode: Make .mpy more compact with qstr directly in prelude.Damien George
Instead of encoding 4 zero bytes as placeholders for the simple_name and source_file qstrs, and storing the qstrs after the bytecode, store the qstrs at the location of these 4 bytes. This saves 4 bytes per bytecode function stored in a .mpy file (for example lcd160cr.mpy drops by 232 bytes, 4x 58 functions). And resulting code size is slightly reduced on ports that use this feature.
2019-10-05py: Add new Xtensa-Windowed arch for native emitter.Damien George
Enabled via the configuration MICROPY_EMIT_XTENSAWIN.
2019-10-01py: Rework and compress second part of bytecode prelude.Damien George
This patch compresses the second part of the bytecode prelude which contains the source file name, function name, source-line-number mapping and cell closure information. This part of the prelude now begins with a single varible length unsigned integer which encodes 2 numbers, being the byte-size of the following 2 sections in the header: the "source info section" and the "closure section". After decoding this variable unsigned integer it's possible to skip over one or both of these sections very easily. This scheme saves about 2 bytes for most functions compared to the original format: one in the case that there are no closure cells, and one because padding was eliminated.
2019-10-01py: Compress first part of bytecode prelude.Damien George
The start of the bytecode prelude contains 6 numbers telling the amount of stack needed for the Python values and exceptions, and the signature of the function. Prior to this patch these numbers were all encoded one after the other (2x variable unsigned integers, then 4x bytes), but using so many bytes is unnecessary. An entropy analysis of around 150,000 bytecode functions from the CPython standard library showed that the optimal Shannon coding would need about 7.1 bits on average to encode these 6 numbers, compared to the existing 48 bits. This patch attempts to get close to this optimal value by packing the 6 numbers into a single, varible-length unsigned integer via bit-wise interleaving. The interleaving scheme is chosen to minimise the average number of bytes needed, and at the same time keep the scheme simple enough so it can be implemented without too much overhead in code size or speed. The scheme requires about 10.5 bits on average to store the 6 numbers. As a result most functions which originally took 6 bytes to encode these 6 numbers now need only 1 byte (in 80% of cases).
2019-09-26py/bc: Replace big opcode format table with simple macro.Damien George
2019-09-18py/persistentcode: Enable persistent code saving for Windows ports.stijn
2019-07-01py/persistentcode: Ensure prelude_offset is always initialised.Paul m. p. P
2019-06-28py/persistentcode: Fix compilation with load and save both enabled.Jun Wu
With both MICROPY_PERSISTENT_CODE_SAVE and MICROPY_PERSISTENT_CODE_LOAD enabled the code fails to compile, due to undeclared 'n_obj'. If MICROPY_EMIT_NATIVE is disabled there are more errors due to the use of undefined fields in mp_raw_code_t. This patch fixes such compilation by avoiding undefined fields. MICROPY_EMIT_NATIVE was changed to MICROPY_EMIT_MACHINE_CODE in this file to match the mp_raw_code_t definition.
2019-05-13py/persistentcode: Change "len" type to size_t for mp_obj_str_get_data.Henrik Vendelbo
2019-05-07mpy-cross: Add --version command line option to print version info.Damien George
Prints something like: MicroPython v1.10-304-g8031b7a25 on 2019-05-02; mpy-cross emitting mpy v4
2019-03-14py/compile: Add support to select the native emitter at runtime.Damien George
2019-03-08py/persistentcode: Bump .mpy version to 4.Damien George
2019-03-08py: Add support to save native, viper and asm code to .mpy files.Damien George
This commit adds support for saving and loading .mpy files that contain native code (native, viper and inline-asm). A lot of the ground work was already done for this in the form of removing pointers from generated native code. The changes here are mainly to link in qstr values to the native code, and change the format of .mpy files to contain native code blocks (possibly mixed with bytecode). A top-level summary: - @micropython.native, @micropython.viper and @micropython.asm_thumb/ asm_xtensa are now allowed in .py files when compiling to .mpy, and they work transparently to the user. - Entire .py files can be compiled to native via mpy-cross -X emit=native and for the most part the generated .mpy files should work the same as their bytecode version. - The .mpy file format is changed to 1) specify in the header if the file contains native code and if so the architecture (eg x86, ARMV7M, Xtensa); 2) for each function block the kind of code is specified (bytecode, native, viper, asm). - When native code is loaded from a .mpy file the native code must be modified (in place) to link qstr values in, just like bytecode (see py/persistentcode.c:arch_link_qstr() function). In addition, this now defines a public, native ABI for dynamically loadable native code generated by other languages, like C.
2019-03-08py/emitglue: Remove union in mp_raw_code_t to combine bytecode & native.Damien George
2019-03-05py/persistentcode: Define static qstr set to reduce size of mpy files.Damien George
When encoded in the mpy file, if qstr <= QSTR_LAST_STATIC then store two bytes: 0, static_qstr_id. Otherwise encode the qstr as usual (either with string data or a reference into the qstr window). Reduces mpy file size by about 5%.
2019-03-05py/persistentcode: Pack qstrs directly in bytecode to reduce mpy size.Damien George
Instead of emitting two bytes in the bytecode for where the linked qstr should be written to, it is now replaced by the actual qstr data, or a reference into the qstr window. Reduces mpy file size by about 10%.
2019-03-05py/persistentcode: Add a qstr window to save mpy files more efficiently.Damien George
This is an implementation of a sliding qstr window used to reduce the number of qstrs stored in a .mpy file. The window size is configured to 32 entries which takes a fixed 64 bytes (16-bits each) on the C stack when loading/saving a .mpy file. It allows to remember the most recent 32 qstrs so they don't need to be stored again in the .mpy file. The qstr window uses a simple least-recently-used mechanism to discard the least recently used qstr when the window overflows (similar to dictionary compression). This scheme only needs a single pass to save/load the .mpy file. Reduces mpy file size by about 25% with a window size of 32.
2019-02-12py: Downcase all MP_OBJ_IS_xxx macros to make a more consistent C API.Damien George
These macros could in principle be (inline) functions so it makes sense to have them lower case, to match the other C API functions. The remaining macros that are upper case are: - MP_OBJ_TO_PTR, MP_OBJ_FROM_PTR - MP_OBJ_NEW_SMALL_INT, MP_OBJ_SMALL_INT_VALUE - MP_OBJ_NEW_QSTR, MP_OBJ_QSTR_VALUE - MP_OBJ_FUN_MAKE_SIG - MP_DECLARE_CONST_xxx - MP_DEFINE_CONST_xxx These must remain macros because they are used when defining const data (at least, MP_OBJ_NEW_SMALL_INT is so it makes sense to have MP_OBJ_SMALL_INT_VALUE also a macro). For those macros that have been made lower case, compatibility macros are provided for the old names so that users do not need to change their code immediately.
2019-01-27py: Remove calls to file reader functions when these are disabled.Sean Burton
If MICROPY_PERSISTENT_CODE_LOAD or MICROPY_ENABLE_COMPILER are enabled then code gets enabled that calls file reading functions which may be disabled if no readers have been implemented. To fix this, introduce a MICROPY_HAS_FILE_READER variable, which is automatically set if MICROPY_READER_POSIX or MICROPY_READER_VFS is set but can also be manually set if a custom reader is being implemented. Then disable the file reading calls if this is not set.
2018-02-14py/emitglue: When assigning bytecode only pass bytecode len if needed.Damien George
Most embedded targets will have this bit of the code disabled, saving a small amount of code space.
2017-10-05py/persistentcode: Bump .mpy version number to version 3.Damien George
The binary and unary ops have changed bytecode encoding.
2017-10-04all: Remove inclusion of internal py header files.Damien George
Header files that are considered internal to the py core and should not normally be included directly are: py/nlr.h - internal nlr configuration and declarations py/bc0.h - contains bytecode macro definitions py/runtime0.h - contains basic runtime enums Instead, the top-level header files to include are one of: py/obj.h - includes runtime0.h and defines everything to use the mp_obj_t type py/runtime.h - includes mpstate.h and hence nlr.h, obj.h, runtime0.h, and defines everything to use the general runtime support functions Additional, specific headers (eg py/objlist.h) can be included if needed.
2017-09-25py/persistentcode: Define mp_raw_code_save_file() for any unix target.Anton Patrushev
A unix target should provide POSIX open/write/close functions regardless of its machine architecture. Fixes issue #3325.
2017-06-08py/persistentcode: Allow to compile with complex numbers disabled.Damien George
2017-04-22py: Add LOAD_SUPER_METHOD bytecode to allow heap-free super meth calls.Damien George
This patch allows the following code to run without allocating on the heap: super().foo(...) Before this patch such a call would allocate a super object on the heap and then load the foo method and call it right away. The super object is only needed to perform the lookup of the method and not needed after that. This patch makes an optimisation to allocate the super object on the C stack and discard it right after use. Changes in code size due to this patch are: bare-arm: +128 minimal: +232 unix x64: +416 unix nanbox: +364 stmhal: +184 esp8266: +340 cc3200: +128
2017-03-14py: Allow lexer to raise exceptions during construction.Damien George
This patch refactors the error handling in the lexer, to simplify it (ie reduce code size). A long time ago, when the lexer/parser/compiler were first written, the lexer and parser were designed so they didn't use exceptions (ie nlr) to report errors but rather returned an error code. Over time that has gradually changed, the parser in particular has more and more ways of raising exceptions. Also, the lexer never really handled all errors without raising, eg there were some memory errors which could raise an exception (and in these rare cases one would get a fatal nlr-not-handled fault). This patch accepts the fact that the lexer can raise exceptions in some cases and allows it to raise exceptions to handle all its errors, which are for the most part just out-of-memory errors during construction of the lexer. This makes the lexer a bit simpler, and also the persistent code stuff is simplified. What this means for users of the lexer is that calls to it must be wrapped in a nlr handler. But all uses of the lexer already have such an nlr handler for the parser (and compiler) so that doesn't put any extra burden on the callers.
2017-02-17py/persistentcode: Bump .mpy version due to change in bytecode.Damien George
2017-02-16py/persistentcode: Replace mp_uint_t with size_t where appropriate.Damien George