aboutsummaryrefslogtreecommitdiff
path: root/py/runtime0.h
AgeCommit message (Collapse)Author
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-01py/nativeglue: Remove unused mp_obj_new_cell from mp_fun_table.Damien George
It has been unused since 9988618e0e0f5c319e31b135d993e22efb593093
2019-10-29py/runtime: Reorder some binary ops so they don't require conditionals.Damien George
runtime0.h is part of the MicroPython ABI so it's simpler if it's independent of config options, like MICROPY_PY_REVERSE_SPECIAL_METHODS. What's effectively done here is to move MP_BINARY_OP_DIVMOD and MP_BINARY_OP_CONTAINS up in the enum, then remove the #if MICROPY_PY_REVERSE_SPECIAL_METHODS conditional. Without this change .mpy files would need to have a feature flag for MICROPY_PY_REVERSE_SPECIAL_METHODS (when embedding native code that uses this enum). This commit has no effect when MICROPY_PY_REVERSE_SPECIAL_METHODS is disabled. With this option enabled this commit reduces code size by about 60 bytes.
2019-10-05py/emitnative: Add support for using setjmp with native emitter.Damien George
To enable this feature the N_NLR_SETJMP macro should be set to 1 before including py/emitnative.c.
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/nativeglue: Make mp_fun_table fixed size regardless of config.Damien George
So that mpy files with native code will always work correctly, and raise an exception if a feature is used that is not supported by the runtime.
2019-09-26py/bc0: Order opcodes into groups based on their size and format.Damien George
2019-09-26py: Add support for matmul operator @ as per PEP 465.Damien George
To make progress towards MicroPython supporting Python 3.5, adding the matmul operator is important because it's a really "low level" part of the language, being a new token and modifications to the grammar. It doesn't make sense to make it configurable because 1) it would make the grammar and lexer complicated/messy; 2) no other operators are configurable; 3) it's not a feature that can be "dynamically plugged in" via an import. And matmul can be useful as a general purpose user-defined operator, it doesn't have to be just for numpy use. Based on work done by Jim Mussared.
2019-09-26py/lexer: Reorder operator tokens to match corresponding binary ops.Damien George
2018-12-07py/obj: Add support for __int__ special method.Paul Sokolovsky
Based on the discussion, this special method is available unconditionally, as converting to int is a common operation.
2018-10-15py/emitnative: Put None/False/True in global native const table.Damien George
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.
2018-10-01py/emitnative: Implement yield and yield-from in native emitter.Damien George
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.
2018-09-27py/emitnative: Place const objs for native code in separate const table.Damien George
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.
2018-09-15py: Make viper functions have the same entry signature as native.Damien George
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.
2018-09-15py/emit: Remove need to call set_native_type to set viper return type.Damien George
Instead this return type is now stored in the scope_flags.
2018-09-13py: Fix native functions so they run with their correct globals context.Damien George
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.
2018-05-23py/emit: Merge build set/slice into existing build emit function.Damien George
Reduces code size by: bare-arm: +0 minimal x86: +0 unix x64: -368 unix nanbox: -248 stm32: -128 cc3200: -48 esp8266: -184 esp32: -40
2017-11-24py/runtime: Add MP_BINARY_OP_CONTAINS as reverse of MP_BINARY_OP_IN.Damien George
Before this patch MP_BINARY_OP_IN had two meanings: coming from bytecode it meant that the args needed to be swapped, but coming from within the runtime meant that the args were already in the correct order. This lead to some confusion in the code and comments stating how args were reversed. It also lead to 2 bugs: 1) containment for a subclass of a native type didn't work; 2) the expression "{True} in True" would illegally succeed and return True. In both of these cases it was because the args to MP_BINARY_OP_IN ended up being reversed twice. To fix these things this patch introduces MP_BINARY_OP_CONTAINS which corresponds exactly to the __contains__ special method, and this is the operator that built-in types should implement. MP_BINARY_OP_IN is now only emitted by the compiler and is converted to MP_BINARY_OP_CONTAINS by swapping the arguments.
2017-10-11py/emitnative: Implement floor-division and modulo for viper emitter.Damien George
2017-10-05py: Clean up unary and binary enum list to keep groups together.Damien George
2 non-bytecode binary ops (NOT_IN and IN_NOT) are moved out of the bytecode group, so this change will change the bytecode format.
2017-09-25py: Clarify which mp_unary_op_t's may appear in the bytecode.Paul Sokolovsky
Not all can, so we don't need to reserve bytecodes for them, and can use free slots for something else later.
2017-09-22py/runtime0: Add comments about unary/binary-op enums used in bytecode.Damien George
2017-09-18py/modbuiltins: Implement abs() by dispatching to MP_UNARY_OP_ABS.Paul Sokolovsky
This allows user classes to implement __abs__ special method, and saves code size (104 bytes for x86_64), even though during refactor, an issue was fixed and few optimizations were made: * abs() of minimum (negative) small int value is calculated properly. * objint_longlong and objint_mpz avoid allocating new object is the argument is already non-negative.
2017-09-10py/runtime: Implement dispatch for "reverse op" special methods.Paul Sokolovsky
If, for class X, X.__add__(Y) doesn't exist (or returns NotImplemented), try Y.__radd__(X) instead. This patch could be simpler, but requires undoing operand swap and operation switch to get non-confusing error message in case __radd__ doesn't exist.
2017-09-08py/runtime0.h: Put inplace arith ops in front of normal operations.Paul Sokolovsky
This is to allow to place reverse ops immediately after normal ops, so they can be tested as one range (which is optimization for reverse ops introduction in the next patch).
2017-09-07py/runtime0.h: Regroup operations a bit.Paul Sokolovsky
Originally, there were grouped in blocks of 5, to make it easier e.g. to assess and numeric code of each. But now it makes more sense to group it by semantics/properties, and then split in chunks still, which usually leads to chunks of ~6 ops.
2017-09-07py/objtype: Make sure mp_binary_op_method_name has full size again.Paul Sokolovsky
After recent refactorings to mp_binary_op_t, and make it future refactoring proof for now, at the cost of extra element in the array.
2017-09-07py/runtime0.h: Move MP_BINARY_OP_DIVMOD to the end of mp_binary_op_t.Paul Sokolovsky
It starts a dichotomy of mp_binary_op_t values which can't appear in the bytecode. Another reason to move it is to VALUES of OP_* and OP_INPLACE_* nicely adjacent. This also will be needed for OP_REVERSE_*, to be soon introduced.
2017-09-07py/runtime0.h: Move relational ops to the beginning of mp_binary_op_t.Paul Sokolovsky
This is to allow to encode arithmetic operations more efficiently, in preparation to introduction of __rOP__ method support.
2017-08-11py/modsys: Initial implementation of sys.getsizeof().Paul Sokolovsky
Implemented as a new MP_UNARY_OP. This patch adds support lists, dicts and instances.
2017-07-31all: Use the name MicroPython consistently in commentsAlexander Steffen
There were several different spellings of MicroPython present in comments, when there should be only one.
2017-07-18all: Unify header guard usage.Alexander Steffen
The code conventions suggest using header guards, but do not define how those should look like and instead point to existing files. However, not all existing files follow the same scheme, sometimes omitting header guards altogether, sometimes using non-standard names, making it easy to accidentally pick a "wrong" example. This commit ensures that all header files of the MicroPython project (that were not simply copied from somewhere else) follow the same pattern, that was already present in the majority of files, especially in the py folder. The rules are as follows. Naming convention: * start with the words MICROPY_INCLUDED * contain the full path to the file * replace special characters with _ In addition, there are no empty lines before #ifndef, between #ifndef and one empty line before #endif. #endif is followed by a comment containing the name of the guard macro. py/grammar.h cannot use header guards by design, since it has to be included multiple times in a single C file. Several other files also do not need header guards as they are only used internally and guaranteed to be included only once: * MICROPY_MPHALPORT_H * mpconfigboard.h * mpconfigport.h * mpthreadport.h * pin_defs_*.h * qstrdefs*.h
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-02-16py: Optimise storage of iterator so it takes only 4 slots on Py stack.Damien George
2016-02-02py: Extend native type-sig to use 4 bits, so uint is separate to ptr.Damien George
Before this patch, the native types for uint and ptr/ptr8/ptr16/ptr32 all overlapped and it was possible to make a mistake in casting. Now, these types are all separate and any coding mistakes will be raised as runtime errors.
2015-12-10py: Make UNARY_OP_NOT a first-class op, to agree with Py not semantics.Damien George
Fixes #1684 and makes "not" match Python semantics. The code is also simplified (the separate MP_BC_NOT opcode is removed) and the patch saves 68 bytes for bare-arm/ and 52 bytes for minimal/. Previously "not x" was implemented as !mp_unary_op(x, MP_UNARY_OP_BOOL), so any given object only needs to implement MP_UNARY_OP_BOOL (and the VM had a special opcode to do the ! bit). With this patch "not x" is implemented as mp_unary_op(x, MP_UNARY_OP_NOT), but this operation is caught at the start of mp_unary_op and dispatched as !mp_obj_is_true(x). mp_obj_is_true has special logic to test for truthness, and is the correct way to handle the not operation.
2015-11-13py: Put all bytecode state (arg count, etc) in bytecode.Damien George
2015-08-17py: Remove unused compile scope flags, and irrelevant flag compute code.Damien George
2015-06-25py: Remove mp_load_const_bytes and instead load precreated bytes object.Damien George
Previous to this patch each time a bytes object was referenced a new instance (with the same data) was created. With this patch a single bytes object is created in the compiler and is loaded directly at execute time as a true constant (similar to loading bignum and float objects). This saves on allocating RAM and means that bytes objects can now be used when the memory manager is locked (eg in interrupts). The MP_BC_LOAD_CONST_BYTES bytecode was removed as part of this. Generated bytecode is slightly larger due to storing a pointer to the bytes object instead of the qstr identifier. Code size is reduced by about 60 bytes on Thumb2 architectures.
2015-06-25py: Remove mp_load_const_str and replace uses with inlined version.Damien George
2015-06-13py: Add MP_BINARY_OP_DIVMOD to simplify and consolidate divmod builtin.Damien George
2015-05-12py: Convert hash API to use MP_UNARY_OP_HASH instead of ad-hoc function.Damien George
Hashing is now done using mp_unary_op function with MP_UNARY_OP_HASH as the operator argument. Hashing for int, str and bytes still go via fast-path in mp_unary_op since they are the most common objects which need to be hashed. This lead to quite a bit of code cleanup, and should be more efficient if anything. It saves 176 bytes code space on Thumb2, and 360 bytes on x86. The only loss is that the error message "unhashable type" is now the more generic "unsupported type for __hash__".
2015-04-07py: Implement full func arg passing for native emitter.Damien George
This patch gets full function argument passing working with native emitter. Includes named args, keyword args, default args, var args and var keyword args. Fully Python compliant. It reuses the bytecode mp_setup_code_state function to do all the hard work. This function is slightly adjusted to accommodate native calls, and the native emitter is forced a bit to emit similar prelude and code-info as bytecode.
2015-04-06py: Implement calling functions with *args in native emitter.Damien George
2015-04-03py: Implement closures in native code generator.Damien George
Currently supports only x64 and Thumb2 archs.
2015-02-08py: Parse big-int/float/imag constants directly in parser.Damien George
Previous to this patch, a big-int, float or imag constant was interned (made into a qstr) and then parsed at runtime to create an object each time it was needed. This is wasteful in RAM and not efficient. Now, these constants are parsed straight away in the parser and turned into objects. This allows constants with large numbers of digits (so addresses issue #1103) and takes us a step closer to #722.
2014-12-27py: Move to guarded includes for compile.h and related headers.Paul Sokolovsky
2014-09-23py: Make native emitter handle multi-compare and not/is not/not in ops.Damien George
2014-09-06py: Native emitter now supports delete name & global, and end finally.Damien George