- May 29, 2019
-
-
Damien George authored
mpy-cross uses MICROPY_DYNAMIC_COMPILER and MICROPY_EMIT_NATIVE but does not actually need to execute native functions, and does not need mp_fun_table. This commit makes it so mp_fun_table and all its entries are not built when MICROPY_DYNAMIC_COMPILER is enabled, significantly reducing the size of the mpy-cross executable and allowing it to be built on more machines/OS's.
-
- May 06, 2019
-
-
Jun Wu authored
Prior to this commit, building the unix port with `DEBUG=1` and `-finstrument-functions` the compilation would fail with an error like "control reaches end of non-void function". This change fixes this by removing the problematic "if (0)" branches. Not all branches affect compilation, but they are all removed for consistency.
-
- May 03, 2019
-
-
Damien George authored
Variables with type bool now act more like an int, and there is proper casting to/from Python objects.
-
- Mar 14, 2019
-
-
Damien George authored
-
Damien George authored
-
- Mar 08, 2019
-
-
Damien George authored
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.
-
Damien George authored
n_obj no longer includes a count for mp_fun_table to make it a bit simpler.
-
Damien George authored
-
Damien George authored
Simplifies the code and fixes handling of the Ellipsis const in native code generation (which also needs the constant table so must set this flag).
-
Damien George authored
The new compile-time option is MICROPY_DEBUG_MP_OBJ_SENTINELS, disabled by default. This is to allow finer control of whether this debugging feature is enabled or not (because, for example, this setting must be the same for mpy-cross and the MicroPython main code when using native code generation).
-
- Mar 05, 2019
-
-
Damien George authored
POP_BLOCK and POP_EXCEPT are now the same, and are always followed by a JUMP. So this optimisation reduces code size, and RAM usage of bytecode by two bytes for each try-except handler.
-
- Feb 25, 2019
-
-
Damien George authored
-
- Oct 14, 2018
-
-
Damien George authored
So these constant objects can be loaded by dereferencing the REG_FUN_TABLE pointer instead of loading immediate values. This reduces the size of generated native code (when such constants are used), and means that pointers to these constants are no longer stored in the assembly code.
-
Damien George authored
This shifts the work of loading the constant None object on to load_reg_stack_imm(), making the handling of None more centralised.
-
Damien George authored
-
Damien George authored
This commit adds the helper function load_reg_stack_imm() which deals with constant immediate values and converting them to Python objects if needed.
-
- Oct 13, 2018
-
-
Damien George authored
-
Damien George authored
-
Damien George authored
The maximum index into mp_fun_table is currently less than 1024 and should stay that way to keep things efficient for all architectures, so there is no need to handle loading the pointer directly via a literal in this function.
-
Damien George authored
All architectures now have a dedicated register to hold the pointer to the native function table mp_fun_table, and so they all need to load this register at the start of the native function. This commit makes the loading of this register uniform across architectures by passing the pointer in the constant table for the native function, and then loading the register from the constant table. Doing it this way means that the pointer is not stored in the assembly code, helping to make the code more portable.
-
Damien George authored
Instead of storing the function pointer directly in the assembly code. This makes the generated code more independent of the runtime (so easier to relocate the code), and reduces the generated code size.
-
Damien George authored
Instead of storing the function pointer directly in the assembly code. This makes the generated code more independent of the runtime (so easier to relocate the code), and reduces the generated code size.
-
- Oct 02, 2018
-
-
Damien George authored
-
- Oct 01, 2018
-
-
Damien George authored
This commit adds first class support for yield and yield-from in the native emitter, including send and throw support, and yields enclosed in exception handlers (which requires pulling down the NLR stack before yielding, then rebuilding it when resuming). This has been fully tested and is working on unix x86 and x86-64, and stm32. Also basic tests have been done with the esp8266 port. Performance of existing native code is unchanged.
-
Damien George authored
The nlr_buf_t doesn't need to be part of the Python value stack (as it was before this commit), it's simpler to have it separated as auxiliary state that lives on the C stack. This will help adding yield support because in that case the nlr_buf_t and Python value stack live in separate memory areas (C stack and heap respectively).
-
- Sep 27, 2018
-
-
Damien George authored
This matches how bytecode does it, and matches the signature of mp_emit_glue_assign_native. Since the native emitter doesn't support nan-boxing uintptr_t and mp_uint_t are anyway the same bit-width.
-
Damien George authored
This commit changes native code to handle constant objects like bytecode: instead of storing the pointers inside the native code they are now stored in a separate constant table (such pointers include objects like bignum, bytes, and raw code for nested functions). This removes the need for the GC to scan native code for root pointers, and takes a step towards making native code independent of the runtime (eg so it can be compiled offline by mpy-cross). Note that the changes to the struct scope_t did not increase its size: on a 32-bit architecture it is still 48 bytes, and on a 64-bit architecture it decreased from 80 to 72 bytes.
-
- Sep 15, 2018
-
-
Damien George authored
Loading a pointer by indexing into the native function table mp_fun_table, rather than loading an immediate value (via a PC-relative load), uses less code space.
-
Damien George authored
Viper functions will now capture the globals at the point they were defined and use these globals when executing.
-
Damien George authored
Old globals are now stored in the second slot (ip in mp_code_state_t) to make things simpler for viper.
-
Damien George authored
-
Damien George authored
This commit makes viper functions have the same signature as native functions, at the level of the emitter/assembler. This means that viper functions can now be wrapped in the same uPy object as native functions. Viper functions are now responsible for parsing their arguments (before it was done by the runtime), and this makes calling them more efficient (in most cases) because the viper entry code can be custom generated to suit the signature of the function. This change also opens the way forward for viper functions to take arbitrary numbers of arguments, and for them to handle globals correctly, among other things.
-
Damien George authored
-
Damien George authored
In viper mode, the type of the argument is now stored in id_info->flags.
-
Damien George authored
Instead this return type is now stored in the scope_flags.
-
Damien George authored
The native emitter can easily determine the mode via scope->emit_options.
-
- Sep 13, 2018
-
-
Damien George authored
Prior to this commit a function compiled with the native decorator @micropython.native would not work correctly when accessing global variables, because the globals dict was not being set upon function entry. This commit fixes this problem by, upon function entry, setting as the current globals dict the globals dict context the function was defined within, as per normal Python semantics, and as bytecode does. Upon function exit the original globals dict is restored. In order to restore the globals dict when an exception is raised the native function must guard its internals with an nlr_push/nlr_pop pair. Because this push/pop is relatively expensive, in both C stack usage for the nlr_buf_t and CPU execution time, the implementation here optimises things as much as possible. First, the compiler keeps track of whether a function even needs to access global variables. Using this information the native emitter then generates three different kinds of code: 1. no globals used, no exception handlers: no nlr handling code and no setting of the globals dict. 2. globals used, no exception handlers: an nlr_buf_t is allocated on the C stack but it is not used if the globals dict is unchanged, saving execution time because nlr_push/nlr_pop don't need to run. 3. function has exception handlers, may use globals: an nlr_buf_t is allocated and nlr_push/nlr_pop are always called. In the end, native functions that don't access globals and don't have exception handlers will run more efficiently than those that do. Fixes issue #1573.
-
- Sep 11, 2018
-
-
Damien George authored
-
- Sep 04, 2018
-
-
Damien George authored
This patch adds full support for unwinding jumps to the native emitter. This means that return/break/continue can be used in try-except, try-finally and with statements. For code that doesn't use unwinding jumps there is almost no overhead added to the generated code.
-
- Sep 03, 2018
-
-
Damien George authored
The native emitter keeps the current exception in a slot in its C stack (instead of on its Python value stack), so when it catches an exception it must explicitly clear that slot so the same exception is not reraised later on.
-