summaryrefslogtreecommitdiff
path: root/py
AgeCommit message (Collapse)Author
2017-12-19py/modio: Use correct config macro to enable resource_stream function.Damien George
2017-12-19py/mpz: Apply a small code-size optimisation.Damien George
2017-12-19py/mpz: Fix pow3 function so it handles the case when 3rd arg is 1.Damien George
In this case the result should always be 0, even if 2nd arg is 0.
2017-12-19py/objset: Remove unneeded check from set_equal.Damien George
set_equal is called only from set_binary_op, and this guarantees that the second arg to set_equal is always a set or frozenset. So there is no need to do a further check.
2017-12-19py/map: Don't include ordered-dict mutating code when not needed.Damien George
2017-12-19py/runtime: Remove unnecessary break statements from switch.Damien George
2017-12-15py/objgenerator: Allow to pend an exception for next execution.Paul Sokolovsky
This implements .pend_throw(exc) method, which sets up an exception to be triggered on the next call to generator's .__next__() or .send() method. This is unlike .throw(), which immediately starts to execute the generator to process the exception. This effectively adds Future-like capabilities to generator protocol (exception will be raised in the future). The need for such a method arised to implement uasyncio wait_for() function efficiently (its behavior is clearly "Future" like, and normally would require to introduce an expensive Future wrapper around all native couroutines, like upstream asyncio does). py/objgenerator: pend_throw: Return previous pended value. This effectively allows to store an additional value (not necessary an exception) in a coroutine while it's not being executed. uasyncio has exactly this usecase: to mark a coro waiting in I/O queue (and thus not executed in the normal scheduling queue), for the purpose of implementing wait_for() function (cancellation of such waiting coro by a timeout).
2017-12-15py/emitglue: Change type of bit-field to explicitly unsigned mp_uint_t.Damien George
Some compilers can treat enum types as signed, in which case 3 bits is not enough to encode all mp_raw_code_kind_t values. So change the type to mp_uint_t.
2017-12-13py/builtinimport: Call __init__ for modules imported via a weak link.Damien George
This is a bit of a clumsy way of doing it but solves the issue of __init__ not running when a module is imported via its weak-link name. Ideally a better solution would be found.
2017-12-12py/objtype: Refactor object's handling of __new__ to not create 2 objs.Damien George
Before this patch, if a user defined the __new__() function for a class then two instances of that class would be created: once before __new__ is called and once during the __new__ call (assuming the user creates some instance, eg using super().__new__, which is most of the time). The first one was then discarded. This refactor makes it so that a new instance is only created if the user __new__ function doesn't exist.
2017-12-12py/objtype: Implement better support for overriding native's __init__.Damien George
This patch cleans up and generalises part of the code which handles overriding and calling a native base-class's __init__ method. It defers the call to the native make_new() function until after the user (Python) __init__() method has run. That user method now has the chance to call the native __init__/make_new and pass it different arguments. If the user doesn't call the super().__init__ method then it will be called automatically after the user code finishes, to finalise construction of the instance.
2017-12-11py/mpstate.h: Remove obsolete comment about nlr_top being coded in asm.Damien George
2017-12-11py: Extend nan-boxing config to have 47-bit small integers.Damien George
The nan-boxing representation has an extra 16-bits of space to store small-int values, and making use of it allows to create and manipulate full 32-bit positive integers (ie up to 0xffffffff) without using the heap.
2017-12-11py/objexcept: Use INT_FMT when printing errno value.Damien George
2017-12-11py/runtime: Use the Python stack when building *arg and **kwarg state.Damien George
With MICROPY_ENABLE_PYSTACK enabled the following language constructs no longer allocate on the heap: f(*arg), f(**kwarg).
2017-12-11py: Convert all uses of alloca() to use new scoped allocation API.Damien George
2017-12-11py: Introduce a Python stack for scoped allocation.Damien George
This patch introduces the MICROPY_ENABLE_PYSTACK option (disabled by default) which enables a "Python stack" that allows to allocate and free memory in a scoped, or Last-In-First-Out (LIFO) way, similar to alloca(). A new memory allocation API is introduced along with this Py-stack. It includes both "local" and "nonlocal" LIFO allocation. Local allocation is intended to be equivalent to using alloca(), whereby the same function must free the memory. Nonlocal allocation is where another function may free the memory, so long as it's still LIFO. Follow-up patches will convert all uses of alloca() and VLA to the new scoped allocation API. The old behaviour (using alloca()) will still be available, but when MICROPY_ENABLE_PYSTACK is enabled then alloca() is no longer required or used. The benefits of enabling this option are (or will be once subsequent patches are made to convert alloca()/VLA): - Toolchains without alloca() can use this feature to obtain correct and efficient scoped memory allocation (compared to using the heap instead of alloca(), which is slower). - Even if alloca() is available, enabling the Py-stack gives slightly more efficient use of stack space when calling nested Python functions, due to the way that compilers implement alloca(). - Enabling the Py-stack with the stackless mode allows for even more efficient stack usage, as well as retaining high performance (because the heap is no longer used to build and destroy stackless code states). - With Py-stack and stackless enabled, Python-calling-Python is no longer recursive in the C mp_execute_bytecode function. The micropython.pystack_use() function is included to measure usage of the Python stack.
2017-12-11py/runtime: Move mp_exc_recursion_depth to runtime and rename to raise.Damien George
For consistency this helper function is renamed to match the other exception helpers, and moved to their location in runtime.c.
2017-12-10unix/mpconfigport: Disable uio.resource_stream().Paul Sokolovsky
This function was implemented as an experiment, and was enabled only in unix port. To remind, it allows to access arbitrary files frozen as source modules (vs bytecode). However, further experimentation showed that the same functionality can be implemented with frozen bytecode. The process requires more steps, but with suitable toolset it doesn't matter patch. This process is: 1. Convert binary files into "Python resource module" with tools/mpy_bin2res.py. 2. Freeze as the bytecode. 3. Use micropython-lib's pkg_resources.resource_stream() to access it. In other words, the extra step is using tools/mpy_bin2res.py (because there would be wrapper for uio.resource_stream() anyway). Going frozen bytecode route allows more flexibility, and same/additional efficiency: 1. Frozen source support can be disabled altogether for additional code savings. 2. Resources could be also accessed as a buffer, not just as a stream. There're few caveats too: 1. It wasn't actually profiled the overhead of storing a resource in "Python resource module" vs storing it directly, but it's assumed that overhead is small. 2. The "efficiency" claim above applies to the case when resource file is frozen as the bytecode. If it's not, it actually will take a lot of RAM on loading. But in this case, the resource file should not be used (i.e. generated) in the first place, and micropython-lib's pkg_resources.resource_stream() implementation has the appropriate fallback to read the raw files instead. This still poses some distribution issues, e.g. to deployable to baremetal ports (which almost certainly would require freezeing as the bytecode), a distribution package should include the resource module. But for non-freezing deployment, presense of resource module will lead to memory inefficiency. All the discussion above reminds why uio.resource_stream() was implemented in the first place - to address some of the issues above. However, since then, frozen bytecode approach seems to prevail, so, while there're still some issues to address with it, this change is being made. This change saves 488 bytes for the unix x86_64 port.
2017-12-10py/mkrules.mk: Add "clean-frozen" target to clean frozen script/modules dir.Paul Sokolovsky
This target removes any stray files (i.e. something not committed to git) from scripts/ and modules/ dirs (or whatever FROZEN_DIR and FROZEN_MPY_DIR is set to). The expected workflow is: 1. make clean-frozen 2. micropython -m upip -p modules <packages_to_freeze> 3. make As it can be expected that people may drop random thing in those dirs which they can miss later, the content is actually backed up before cleaning.
2017-12-09py/map: Allow to trace rehashing operations.Paul Sokolovsky
2017-12-09py/objfun: Factor out macro for initializing codestate.Paul Sokolovsky
This is second part of fun_bc_call() vs mp_obj_fun_bc_prepare_codestate() common code refactor. This factors out code to initialize codestate object. After this patch, mp_obj_fun_bc_prepare_codestate() is effectively DECODE_CODESTATE_SIZE() followed by allocation followed by INIT_CODESTATE(), and fun_bc_call() starts with that too.
2017-12-09py/objfun, vm: Add comments on codestate allocation in stackless mode.Paul Sokolovsky
2017-12-09py/objfun: Factor out macro for decoding codestate size.Paul Sokolovsky
fun_bc_call() starts with almost the same code as mp_obj_fun_bc_prepare_codestate(), the only difference is a way to allocate the codestate object (heap vs stack with heap fallback). Still, would be nice to avoid code duplication to make further refactoring easier. So, this commit factors out the common code before the allocation - decoding and calculating codestate size. It produces two values, so structured as a macro which writes to 2 variables passed as arguments.
2017-12-09py/gc: In sweep debug output, print pointer as a pointer.Paul Sokolovsky
Or it will be truncated on a 64-bit platform.
2017-12-09py/gc: Factor out a macro to trace GC mark operations.Paul Sokolovsky
To allow easier override it for custom tracing.
2017-12-09py/runtime: When tracing unary/binary ops, output op (method) name.Paul Sokolovsky
E.g.: >>> 1+1 binary 26 __add__ 3 3 Output is similar to bytecode dump (numeric code, then op name).
2017-12-08py/objint_longlong: Check for zero division/modulo.Paul Sokolovsky
2017-12-08py/asmbase: Revert removal of clearing of label offsets for native emit.Damien George
The assembler back-end for most architectures needs to know if a jump is backwards in order to emit optimised machine code, and they do this by checking if the destination label has been set or not. So always reset label offsets to -1 (this reverts partially the previous commit, with some minor optimisation for the if-logic with the pass variable).
2017-12-08py/{emitbc,asmbase}: Only clear emit labels to -1 when in debug mode.Damien George
Clearing the labels to -1 is purely a debugging measure. For release builds there is no need to do it as the label offset table should always have the correct value assigned.
2017-12-08py/gc: Add CLEAR_ON_SWEEP option to debug mis-traced objects.Paul Sokolovsky
Accessing them will crash immediately instead still working for some time, until overwritten by some other data, leading to much less deterministic crashes.
2017-12-07py/malloc: Allow to use debug logging if !MICROPY_MALLOC_USES_ALLOCATED_SIZE.Paul Sokolovsky
This is mostly a workaround for forceful rebuilding of mpy-cross on every codebase change. If this file has debug logging enabled (by patching), mpy-cross build failed.
2017-12-07py/malloc: MICROPY_MEM_STATS requires MICROPY_MALLOC_USES_ALLOCATED_SIZE.Paul Sokolovsky
Error out if they're set incompatibly.
2017-12-07py/mpprint: Fix "%x" vs "%X" regression introduced in previous commit.Paul Sokolovsky
2017-12-07py/mpprint: Support "%lx" format on 64-bit systems.Paul Sokolovsky
Before that, the output was truncated to 32 bits. Only "%x" format is handled, because a typical use is for addresses. This refactor actually decreased x86_64 code size by 30 bytes.
2017-12-07py/mpprint: Make "%p" format work properly on 64-bit systems.Paul Sokolovsky
Before, the output was truncated to 32 bits.
2017-12-05py/modbuiltins: Use standard arg-parsing helper func for builtin print.Damien George
This allows the function to raise an exception when unknown keyword args are passed in. This patch also reduces code size by (in bytes): bare-arm: -24 minimal x86: -76 unix x64: -56 unix nanbox: -84 stm32: -40 esp8266: -68 cc3200: -48 Furthermore, this patch adds space (" ") to the set of ROM qstrs which means it doesn't need to be put in RAM if it's ever used.
2017-12-05py: mp_call_function_*_protected(): Pass-thru return value if possible.Paul Sokolovsky
Return the result of called function. If exception happened, return MP_OBJ_NULL. Allows to use mp_call_function_*_protected() with callbacks returning values, etc.
2017-12-04py/misc.h: Add m_new_obj_var_with_finaliser().Paul Sokolovsky
Similar to existing m_new_obj_with_finaliser().
2017-11-30py/objgenerator: Remove unreachable code for STOP_ITERATION case.Damien George
This commit essentially reverts aa9dbb1b033a8163e07fcf5763fc20146354cc48 where this if-condition was added. It seems that even when that commit was made the code was never reached by any tests, nor reachable by analysis (see below). The same is true with the code as it currently stands: no test triggers this if-condition, nor any uasyncio examples. Analysing the flow of the program also shows that it's not reachable: ==START== -> to trigger this if condition mp_execute_bytecode() must return MP_VM_RETURN_YIELD with *sp==MP_OBJ_STOP_ITERATION -> mp_execute_bytecode() can only return MP_VM_RETURN_YIELD from the MP_BC_YIELD_VALUE bytecode, which can happen in 2 ways: -> 1) from a "yield <x>" in bytecode, but <x> must always be a proper object, never MP_OBJ_STOP_ITERATION; ==END1== -> 2) via yield from, via mp_resume() which must return MP_VM_RETURN_YIELD with ret_value==MP_OBJ_STOP_ITERATION, which can happen in 3 ways: -> 1) it delegates to mp_obj_gen_resume(); go back to ==START== -> 2) it returns MP_VM_RETURN_YIELD directly but with a guard that ret_val!=MP_OBJ_STOP_ITERATION; ==END2== -> 3) it returns MP_VM_RETURN_YIELD with ret_val set from mp_call_method_n_kw(), but mp_call_method_n_kw() must return a proper object, never MP_OBJ_STOP_ITERATION; ==END3== The above shows there is no way to trigger the if-condition and it can be removed.
2017-11-29py/gc: In gc_realloc, convert pointer sanity checks to assertions.Damien George
These checks are assumed to be true in all cases where gc_realloc is called with a valid pointer, so no need to waste code space and time checking them in a non-debug build.
2017-11-29py/qstr: Rewrite find_qstr to make manifest that it returns a valid ptr.Damien George
So long as the input qstr identifier is valid (below the maximum number of qstrs) the function will always return a valid pointer. This patch eliminates the "return 0" dead-code.
2017-11-29py: Annotate func defs with NORETURN when their corresp decls have it.Damien George
2017-11-27py/objdict: Reuse dict-view key iterator for standard dict iterator.Damien George
It has equivalent behaviour and reusing it saves some code bytes.
2017-11-27py/parsenum: Improve parsing of floating point numbers.Damien George
This patch improves parsing of floating point numbers by converting all the digits (integer and fractional) together into a number 1 or greater, and then applying the correct power of 10 at the very end. In particular the multiple "multiply by 0.1" operations to build a fraction are now combined together and applied at the same time as the exponent, at the very end. This helps to retain precision during parsing of floats, and also includes a check that the number doesn't overflow during the parsing. One benefit is that a float will have the same value no matter where the decimal point is located, eg 1.23 == 123e-2.
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-11-24py/opmethods: Include the correct header for binary op enums.Damien George
By directly including runtime0.h the mpconfig.h settings are not included and so the enums in runtime0.h can be incorrect.
2017-11-24py/runtime: Simplify handling of containment binary operator.Damien George
In mp_binary_op, there is no need to explicitly check for type->getiter being non-null and raising an exception because this is handled exactly by mp_getiter(). So just call the latter unconditionally.
2017-11-22py/modbuiltins: Slightly simplify code in builtin round().Damien George
2017-11-21py/objfloat: Allow float() to parse anything with the buffer protocol.Damien George
This generalises and simplifies the code and follows CPython behaviour.