Commit Graph

3406 Commits

Author SHA1 Message Date
Damien George 746dbf78d3 py/py.mk: When building axtls use -Wno-all to prevent all warnings.
Building axtls gives a lot of warnings with -Wall enabled, and explicitly
disabling all of them cannot be done in a way compatible with gcc and
clang, and likely other compilers.  So just use -Wno-all to prevent all of
the extra warnings (in addition to the necessary -Wno-unused-parameter,
-Wno-uninitialized, -Wno-sign-compare and -Wno-old-style-definition).

Fixes issue #4182.
2018-10-27 23:53:08 +11:00
Paul m. p. P 454cca6016 py/objmodule: Implement PEP 562's __getattr__ for modules.
Configurable via MICROPY_MODULE_GETATTR, disabled by default.  Among other
things __getattr__ for modules can help to build lazy loading / code
unloading at runtime.
2018-10-23 11:22:50 +11:00
Paul Sokolovsky 5a91fce9f8 py/objstr: Make str.count() method configurable.
Configurable via MICROPY_PY_BUILTINS_STR_COUNT.  Default is enabled.
Disabled for bare-arm, minimal, unix-minimal and zephyr ports.  Disabling
it saves 408 bytes on x86.
2018-10-22 22:49:05 +11:00
Damien George 7eb29c2000 py/objtype: Remove comment about catching exc from user __getattr__.
Any exception raised in a user __getattr__ should be propagated out.  A
test is added to verify these semantics.
2018-10-18 12:15:16 +11:00
Damien George de71035e02 py/emitnative: Put None/False/True in global native const table.
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-15 00:20:49 +11:00
Damien George 6c6050ca43 py/emitnative: Push internal None rather than const obj where possible.
This shifts the work of loading the constant None object on to
load_reg_stack_imm(), making the handling of None more centralised.
2018-10-15 00:20:49 +11:00
Damien George 7c16bc0406 py/emitnative: Simplify viper mode handling in emit_native_import_name. 2018-10-15 00:20:49 +11:00
Damien George 175739cd37 py/emitnative: Consolidate use of stacked immediate values to one func.
This commit adds the helper function load_reg_stack_imm() which deals with
constant immediate values and converting them to Python objects if needed.
2018-10-15 00:20:49 +11:00
Damien George 6bda951d4d py/emitnative: Remove unused ptr argument from ASM_CALL_IND macro. 2018-10-13 15:16:33 +11:00
Damien George 25571800fc py/asmthumb: Remove unused fun_ptr arg from asm_thumb_bl_ind function. 2018-10-13 15:16:33 +11:00
Damien George 5f1dd5b86b py/asmarm: Simplify asm_arm_bl_ind to only load via index, not literal.
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.
2018-10-13 15:16:33 +11:00
Damien George 006671056d py/emitnative: Load native fun table ptr from const table for all archs.
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.
2018-10-13 15:16:33 +11:00
Damien George 355eb8eafb py/asmx86: Change indirect calls to load fun ptr from the native table.
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.
2018-10-13 15:16:33 +11:00
Damien George b7c6f859d0 py/asmx86: Change stack management to reference locals by esp not ebp.
The esp register is always a fixed distance below ebp, and using esp to
reference locals on the stack frees up the ebp register for general purpose
use (which is important for an architecture with only 8 user registers).
2018-10-13 15:16:33 +11:00
Damien George 8e4b4bac70 py/asmx64: Change indirect calls to load fun ptr from the native table.
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.
2018-10-13 15:16:33 +11:00
Damien George 8941c63290 py/asmx64: Change stack management to reference locals by rsp not rbp.
The rsp register is always a fixed distance below rbp, and using rsp to
reference locals on the stack frees up the rbp register for general purpose
use.
2018-10-13 15:16:33 +11:00
Damien George 34af10d2ef py/emitnative: Clean up unused macro and forward function declarations. 2018-10-02 15:01:56 +10:00
Damien George 69e7903904 py/obj.h: Use uint64_t instead of mp_int_t in repr-D MP_OBJ_IS_x macros.
This follows how it's already done in MP_OBJ_IS_OBJ: the objects are
considered 64-bit unsigned ints for the purpose of bitwise manipulation.
2018-10-01 16:36:46 +10:00
Damien George a9237cee82 py/runtime: Remove comment in mp_import_name about level being 0.
A non-zero level has been supported for some time now.
2018-10-01 15:35:10 +10:00
Damien George 4ab397576f py/runtime: Use mp_import_name to implement tail of mp_import_from. 2018-10-01 15:22:03 +10:00
Damien George cc2bd63c57 py/emitnative: Implement yield and yield-from in native emitter.
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-10-01 13:31:11 +10:00
Damien George 8fec6f5434 py/emitnative: Reorder native state on C stack so nlr_buf_t is first.
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).
2018-10-01 12:36:21 +10:00
Damien George 4fc437f1ef py/asmxtensa: Use proper calculation for const table offset.
Instead of hard-coding it to 4 bytes.  This allows for there to be other
data stored at the very start of the emitted native code.
2018-10-01 12:34:58 +10:00
Damien George 5b19916d6e py/asmx64: Extend asm_x64_mov_reg_pcrel to accept high registers. 2018-10-01 12:34:36 +10:00
Damien George 1dc720dc01 py/asmx86: Comment out unused asm_x86_nop to prevent compiler warnings. 2018-10-01 12:34:23 +10:00
Damien George 87231132d4 py/asmthumb: Extend asm entry/exit to handle stack larger than 508 bytes 2018-09-30 23:31:17 +10:00
Damien George ef9394e76a py/asmthumb: Clean up asm_thumb_bl_ind to use new optimised ldr helper. 2018-09-30 23:30:18 +10:00
Damien George 07ccb192c5 py/asmthumb: Add wide ldr to handle larger offsets.
In particular this allows native functions on Thumb2 to index more than 32
constants in the constant table.
2018-09-30 23:27:01 +10:00
Damien George d95947b48a py/vm: When VM raises exception put exc obj at beginning of func state.
Instead of at end of state, n_state - 1.  It was originally (way back in
v1.0) put at the end of the state because the VM didn't have a pointer to
the start.  But now that the VM takes a mp_code_state_t pointer it does
have a pointer to the start of the state so can put the exception object
there.

This commit saves about 30 bytes of code on all architectures, and, more
importantly, reduces C-stack usage by a couple of words (8 bytes on Thumb2
and 16 bytes on x86-64) for every (non-generator) call of a bytecode
function because fun_bc_call no longer needs to remember the n_state
variable.
2018-09-29 23:25:08 +10:00
Damien George dd288904db py/objtype: Support full object model for get/set/delitem special meths.
This makes these special methods have the same calling behaviour as other
methods in a class instance (mp_convert_member_lookup() is already called
by mp_obj_class_lookup()).
2018-09-28 23:22:34 +10:00
Damien George 2eb0170157 py/objtype: Remove TODO about storing attributes to classes.
This behaviour is tested in basics/class_store.py and follows CPython.
2018-09-28 23:15:12 +10:00
Damien George 2c7a3061d5 py/runtime: Remove nlr protection when calling __next__ in mp_resume.
And remove related comment about needing such protection when calling send.

Reasoning for removal is as follows:
- mp_resume is only called by the VM in YIELD_FROM opcode
- if send_value != MP_OBJ_NULL then throw_value == MP_OBJ_NULL
- so if __next__ or send are called then throw_value == MP_OBJ_NULL
- if __next__ or send raise an exception without nlr protection then the
  exception will be handled by the global exception handler of the VM
- this handler already has code to handle exceptions raised in YIELD_FROM,
  including correct handling of StopIteration
- this handler doesn't handle the case of injection of GeneratorExit, but
  this won't be needed because throw_value == MP_OBJ_NULL

Note that it's already possible for mp_resume() to raise an exception
(including StopIteration) from the unprotected call to type->iternext(), so
that's why the VM already has code to handle the case of exceptions coming
out of mp_resume().

This commit reduces code size by a bit, and significantly reduces C stack
usage when using yield-from, from 88 bytes down to 40 for Thumb2, and 152
down to 72 bytes for x86-64 (better than half).  (Note that gcc doesn't
seem to tail-call optimise the call from mp_resume() to mp_obj_gen_resume()
so this saving in C stack usage helps all uses of yield-from.)
2018-09-28 22:16:56 +10:00
Damien George 0c9d452370 py/vm: Fix case of throwing GeneratorExit type into yield-from.
mp_make_raise_obj must be used to convert a possible exception type to an
instance object, otherwise the VM may raise a non-exception object.

An existing test is adjusted to test this case, with the original test
already moved to generator_throw.py.
2018-09-28 11:39:35 +10:00
Damien George e9012a20f7 py/emitnative: Change type of const_table from uintptr_t to mp_uint_t.
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.
2018-09-28 00:04:10 +10:00
Damien George 2e86233263 py/asm*: Remove ASM_MOV_REG_ALIGNED_IMM emit macro, it's no longer used.
After the previous commit this macro is no longer needed by the native
emitter because live heap pointers are no longer stored in generated native
machine code.
2018-09-27 23:39:08 +10:00
Damien George 7d4b6cc868 py/emitnative: Place const objs for native code in separate const table.
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-27 23:39:08 +10:00
Damien George b3eadf3f3d py/objfloat: Fix abs(-0.0) so it returns 0.0.
Nan and inf (signed and unsigned) are also handled correctly by using
signbit (they were also handled correctly with "val<0", but that didn't
handle -0.0 correctly).  A test case is added for this behaviour.
2018-09-27 15:21:25 +10:00
Damien George fc1bb51af5 py/objgenerator: Remove TODO about returning gen being called again.
The code implements correct behaviour, as tested by the new test case added
in this commit.
2018-09-27 15:18:24 +10:00
Damien George 6d20be31ae py/vm: Reword TODO about invalid ip/sp after an exception to a note. 2018-09-27 15:17:37 +10:00
Damien George 04f7da78db py/objmodule: Remove TODO about checking store attr to a module.
The code implements correct behaviour, as tested by basics/module1.py.
2018-09-27 15:16:24 +10:00
Damien George cc5c3c64ca py/objint: Remove TODO about checking of int() arg types with 2 args.
The arguments are checked by mp_obj_str_get_data and mp_obj_get_int.
2018-09-27 15:15:29 +10:00
Damien George 814f17a3a4 py/objdict: Reword TODO about inlining mp_obj_dict_get to a note. 2018-09-27 15:14:12 +10:00
Damien George baa83a0c6d py/objslice: Remove long-obsolete comment about enhancing slice object.
Commit afaaf535e6 made this comment obsolete.
2018-09-27 11:23:31 +10:00
Damien George 76355c8863 py/vm: Make small optimisation of BUILD_SLICE opcode.
No need to call DECODE_UINT since the value will always be either 2 or 3.
2018-09-27 11:22:33 +10:00
stijn 57a7d5be9a py: Fix msvc C++ compiler warnings with MP_OBJ_FUN_MAKE_SIG macro.
When obj.h is compiled as C++ code, the cl compiler emits a warning about
possibly unsafe mixing of size_t and bool types in the or operation in
MP_OBJ_FUN_MAKE_SIG.  Similarly there's an implicit narrowing integer
conversion in runtime.h.  This commit fixes this by being explicit.
2018-09-26 15:34:59 +10:00
Paul Sokolovsky a135bca4a1 py/objstr: format: Return bytes result for bytes format string.
This is an improvement over previous behavior when str was returned for
both str and bytes input format.  This new behaviour is also consistent
with how the % operator works, as well as many other str/bytes methods.

It should be noted that it's not how current versions of CPython work,
where there's a gap in the functionality and bytes.format() is not
supported.
2018-09-26 15:29:41 +10:00
Christopher Swenson 8c656754aa py/modmath: Add math.factorial, optimised and non-opt implementations.
This commit adds the math.factorial function in two variants:
- squared difference, which is faster than the naive version, relatively
  compact, and non-recursive;
- a mildly optimised recursive version, faster than the above one.

There are some more optimisations that could be done, but they tend to take
more code, and more storage space.  The recursive version seems like a
sensible compromise.

The new function is disabled by default, and uses the non-optimised version
by default if it is enabled.  The options are MICROPY_PY_MATH_FACTORIAL
and MICROPY_OPT_MATH_FACTORIAL.
2018-09-26 15:03:04 +10:00
Romain Goyet b768cc6ca8 py/parsenum: Avoid rounding errors with negative powers-of-10.
This patches avoids multiplying with negative powers-of-10 when parsing
floating-point values, when those powers-of-10 can be exactly represented
as a positive power.  When represented as a positive power and used to
divide, the resulting float will not have any rounding errors.

The issue is that mp_parse_num_decimal will sometimes not give the closest
floating representation of the input string.  Eg for "0.3", which can't be
represented exactly in floating point, mp_parse_num_decimal gives a
slightly high (by 1LSB) result.  This is because it computes the answer as
3 * 0.1, and since 0.1 also can't be represented exactly, multiplying by 3
multiplies up the rounding error in the 0.1.  Computing it as 3 / 10, as
now done by the change in this commit, gives an answer which is as close to
the true value of "0.3" as possible.
2018-09-20 22:06:41 +10:00
Damien George 3f6ffe059f py/objgenerator: Implement PEP479, StopIteration convs to RuntimeError.
This commit implements PEP479 which disallows raising StopIteration inside
a generator to signal that it should be finished.  Instead, the generator
should simply return when it is complete.

See https://www.python.org/dev/peps/pep-0479/ for details.
2018-09-20 15:36:59 +10:00
Paul Sokolovsky 93f29975db py/modbuiltins: Make oct/hex work when !MICROPY_PY_BUILTINS_STR_OP_MODULO
Instead of redirecting to str.__mod__(), use str.format() in this case.
2018-09-20 14:41:35 +10:00
Paul Sokolovsky 2da5d41350 py/objstr: Make % (__mod__) formatting operator configurable.
Default is enabled, disabled for minimal builds. Saves 1296 bytes on x86,
976 bytes on ARM.
2018-09-20 14:41:08 +10:00
Damien George b01f66c5f1 py: Shorten error messages by using contractions and some rewording. 2018-09-20 14:33:10 +10:00
Damien George 0a36a80f96 py/objtype: Clarify comment about configuring inplace op methods.
In 0e80f345f8 the inplace operations __iadd__
and __isub__ were made unconditionally available, so the comment about this
section is changed to reflect that.
2018-09-20 11:42:56 +10:00
Damien George 7e3dd9f8a3 py/asmthumb: Detect presence of I-cache using CMSIS macro.
Fixes issue #4113.
2018-09-16 01:50:45 +10:00
Damien George 30a45360e7 py/asmxtensa: Make indirect calls using func table, not raw pointers.
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.
2018-09-16 00:43:24 +10:00
Damien George 93d71c5436 py/emitnative: Make viper funcs run with their correct globals context.
Viper functions will now capture the globals at the point they were defined
and use these globals when executing.
2018-09-15 22:39:27 +10:00
Damien George f12e039c2b py/emitnative: Use macros instead of raw offsetof for slot locations.
Old globals are now stored in the second slot (ip in mp_code_state_t) to
make things simpler for viper.
2018-09-15 22:39:27 +10:00
Damien George a676b5acf6 py/emitnative: Support arbitrary number of arguments to viper functions. 2018-09-15 22:39:27 +10:00
Damien George 43f1848bfa py: Make viper functions have the same entry signature as native.
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-15 22:39:27 +10:00
Damien George 460954734e py/emitnative: Reuse mp_native_type_from_qstr when searching for a cast. 2018-09-15 13:52:58 +10:00
Damien George 9f2067288a py/compile: Factor code that compiles viper type annotations. 2018-09-15 13:44:39 +10:00
Damien George a169a5848c py/compile: Merge viper annotation and normal param compilation stages.
Now that the compiler can store the results of the viper types in the
scope, the viper parameter annotation compilation stage can be merged with
the normal parameter compilation stage.
2018-09-15 13:20:54 +10:00
Damien George 80db30a510 py/emit: Completely remove set_native_type, arg type is set in compiler.
In viper mode, the type of the argument is now stored in id_info->flags.
2018-09-15 13:00:11 +10:00
Damien George 07caf4f969 py/emit: Remove need to call set_native_type to set viper return type.
Instead this return type is now stored in the scope_flags.
2018-09-15 12:41:25 +10:00
Damien George 1d7c221b30 py/emit: Remove need to call set_native_type to set native/viper mode.
The native emitter can easily determine the mode via scope->emit_options.
2018-09-15 12:17:14 +10:00
Damien George 3751512e9d py/emit: Move MP_EMIT_OPT_xxx enums from compile.h to emitglue.h. 2018-09-15 12:17:09 +10:00
Damien George abb536da49 py/{asmx86,asmx64}: Extend test_r8_with_r8 to accept all 8 lower regs. 2018-09-14 17:38:09 +10:00
Damien George dd522d63b6 py/asmx64: Fix bug in assembler when creating disp with r13 and 0 offset 2018-09-14 17:36:09 +10:00
Damien George 9f241ef398 py: Optimise call to mp_arg_check_num by compressing fun signature.
With 5 arguments to mp_arg_check_num(), some architectures need to pass
values on the stack.  So compressing n_args_min, n_args_max, takes_kw into
a single word and passing only 3 arguments makes the call more efficient,
because almost all calls to this function pass in constant values.  Code
size is also reduced by a decent amount:

   bare-arm:  -116
minimal x86:   -64
   unix x64:  -256
unix nanbox:  -112
      stm32:  -324
     cc3200:  -192
    esp8266:  -192
      esp32:  -144
2018-09-14 13:39:17 +10:00
Damien George 4f3d9429b5 py: Fix native functions so they run with their correct globals context.
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-09-13 22:47:20 +10:00
Damien George f2de9d60f7 py/emitnative: Fix try-finally in outer scope, so finally is cancelled. 2018-09-11 15:33:25 +10:00
Paul Sokolovsky 674e069ba9 py/objarray: bytearray: Allow 2nd/3rd arg to constructor.
If bytearray is constructed from str, a second argument of encoding is
required (in CPython), and third arg of Unicode error handling is allowed,
e.g.:

bytearray("str", "utf-8", "strict")

This is similar to bytes:

bytes("str", "utf-8", "strict")

This patch just allows to pass 2nd/3rd arguments to bytearray, but
doesn't try to validate them to not impact code size. (This is also
similar to how bytes constructor is handled, though it does a bit
more validation, e.g. check that in case of str arg, encoding argument
is passed.)
2018-09-11 15:10:10 +10:00
Paul Sokolovsky 5fe3730a30 extmod/moduhashlib: Add md5 implementation, using axTLS.
MD5 is still widely used, and may be important in some cases for networking
interoperability, e.g. HTTP Digest authentication.
2018-09-11 14:51:52 +10:00
stijn 89516b2b62 py/runtime: Fix incorrect test for MICROPY_PORT_DEINIT_FUNC. 2018-09-11 00:38:31 +10:00
Damien George 0be2ea50e9 py/py.mk: Build axtls library directly from its source files.
This removes the need for a separate axtls build stage, and builds all
axtls object files along with other code.  This simplifies and cleans up
the build process, automatically builds axtls when needed, and puts the
axtls object files in the correct $(BUILD) location.

The MicroPython axtls configuration file is provided in
extmod/axtls-include/config.h
2018-09-08 00:07:23 +10:00
Damien George 8014e7f15f py/compile: Factor code that compiles start/end of exception handler. 2018-09-04 16:06:22 +10:00
Damien George 4ae7111573 py/emitnative: Add support for return/break/continue in try and with.
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.
2018-09-04 14:31:28 +10:00
Damien George 3cd2c281d7 py/emitnative: Cancel caught exception once handled to prevent reraise.
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.
2018-09-03 17:41:02 +10:00
Damien George b735208403 py/vm: Fix handling of finally-return with complex nested finallys.
Back in 8047340d75 basic support was added in
the VM to handle return statements within a finally block.  But it didn't
cover all cases, in particular when some finally's were active and others
inactive when the "return" was executed.

This patch adds further support for return-within-finally by correctly
managing the currently_in_except_block flag, and should fix all cases.  The
main point is that finally handlers remain on the exception stack even if
they are active (currently being executed), and the unwind return code
should only execute those finally's which are inactive.

New tests are added for the cases which now pass.
2018-09-03 13:08:16 +10:00
Damien George 4f9842ad80 py/emitnx86: Fix number of args passed to mp_setup_code_state, 4 not 5. 2018-08-17 15:03:51 +10:00
Damien George 794c32102e py/asmxtensa: Use narrow version of add instr to reduce native code size 2018-08-17 14:53:58 +10:00
Damien George a0a29724c8 py/emitnative: Fix bug with store of 16 and 32 values in viper ARM mode. 2018-08-17 14:11:37 +10:00
Damien George 1ad44acb15 py/asmxtensa: Optimise loading local addr and support larger offsets. 2018-08-17 14:11:37 +10:00
Damien George fd10a11c6b py/asmxtensa: Fix bug with order of regs in addi encoding. 2018-08-17 14:11:37 +10:00
Damien George a3de776486 py/emitnative: Optimise and improve exception handling in native code.
Prior to this patch, native code would use a full nlr_buf_t for each
exception handler (try-except, try-finally, with).  For nested exception
handlers this would use a lot of C stack and be rather inefficient.

This patch changes how exceptions are handled in native code by setting up
only a single nlr_buf_t context for the entire function, and then manages a
state machine (using the PC) to work out which exception handler to run
when an exception is raised by an nlr_jump.  This keeps the C stack usage
at a constant level regardless of the depth of Python exception blocks.

The patch also fixes an existing bug when local variables are written to
within an exception handler, then their value was incorrectly restored if
an exception was raised (since the nlr_jump would restore register values,
back to the point of the nlr_push).

And it also gets nested try-finally+with working with the viper emitter.

Broadly speaking, efficiency of executing native code that doesn't use
any exception blocks is unchanged, and emitted code size is only slightly
increased for such function.  C stack usage of all native functions is
either equal or less than before.  Emitted code size for native functions
that use exception blocks is increased by roughly 10% (due in part to
fixing of above-mentioned bugs).

But, most importantly, this patch allows to implement more Python features
in native code, like unwind jumps and yielding from within nested exception
blocks.
2018-08-16 13:56:36 +10:00
Damien George 2964b41c28 py/asm*: Support assembling code to jump to a register, and get PC+off.
Useful for position independent code, and implementing state machines.
2018-08-16 13:45:24 +10:00
Damien George f7d6108d1a py/asmxtensa: Handle function entry/exit when stack use larger than 127. 2018-08-16 13:43:36 +10:00
Damien George 8c49995398 py/emitnative: Use small tables to simplify handling of local regs. 2018-08-15 10:55:11 +10:00
Damien George b8b2525576 extmod/modbtree: Update to work with new mp_stream_posix_XXX signatures. 2018-08-14 17:41:23 +10:00
Damien George 9ab816d676 py/stream: Adjust mp_stream_posix_XXX to take void*, not mp_obj_t.
These POSIX wrappers are assumed to be passed a concrete stream object so
it is more efficient (eg on nan-boxing builds) to pass in the pointer
rather than mp_obj_t, because then the users of these functions only need
to store a void* (and mp_obj_t may be wider than a pointer).  And things
would be further improved if the stream protocol functions eventually took
a pointer as their first argument (instead of an mp_obj_t).

This patch is a step to getting ussl/axtls compiling on nan-boxing builds.

See issue #3085.
2018-08-14 17:36:08 +10:00
Damien George a785a3dbfb py/objarray: Allow to build again when bytearray is disabled. 2018-08-14 16:23:21 +10:00
Damien George 91041945c9 py/gc: In gc_alloc, reset n_free var right before search for free mem.
Otherwise there is the possibility that n_free starts out non-zero from the
previous iteration, which may have found a few (but not enough) free blocks
at the end of the heap.  If this is the case, and if the very first blocks
that are scanned the second time around (starting at
gc_last_free_atb_index) are found to give enough memory (including the
blocks at the end of the heap from the previous iteration that left n_free
non-zero) then memory will be allocated starting before the location that
gc_last_free_atb_index points to, most likely leading to corruption.

This serious bug did not manifest itself in the past because a gc_collect
always resets gc_last_free_atb_index to point to the start of the GC heap,
and the first block there is almost always allocated to a long-lived
object (eg entries from sys.path, or mounted filesystem objects), which
means that n_free would be reset at the start of the search loop.

But with threading enabled with the GIL disabled it is possible to trigger
the bug via the following sequence of events:

1. Thread A runs gc_alloc, fails to find enough memory, and has a non-zero
   n_free at the end of the search.
2. Thread A calls gc_collect and frees a bunch of blocks on the GC heap.
3. Just after gc_collect finishes in thread A, thread B takes gc_mutex and
   does an allocation, moving gc_last_free_atb_index to point to the
   interior of the heap, to a place where there is most likely a run of
   available blocks.
4. Thread A regains gc_mutex and does its second search for free memory,
   starting with a non-zero n_free.  Since it's likely that the first block
   it searches is available it will allocate memory which overlaps with the
   memory before gc_last_free_atb_index.
2018-08-14 16:11:21 +10:00
Paul Sokolovsky bb28fe7b7b py/py.mk: Don't hardcode path to libaxtls.a.
Use -L$(BUILD), not -Lbuild. Otherwise, builds for different archs/subarchs
using different values of BUILD may fail.
2018-08-14 15:10:52 +10:00
Damien George cbec17f2cd py/compile: For dynamic compiler, widen literal 1 to get correct shift.
Without this patch, on 64-bit architectures the "1 << (small_int_bits - 1)"
is computed using only 32-bit values (since small_int_bits is a uint8_t)
and so will overflow (and give the wrong result) if small_int_bits is
larger than 32.
2018-08-13 23:34:47 +10:00
Damien George 17b512020b py/emitnative: Allocate space for local stack info as it's needed. 2018-08-07 16:19:38 +10:00
Damien George 652a58698e py/emitnative: Simplify handling of exception objects from nlr_buf_t.
There is no need to have three copies of the exception object on the top of
the native value stack.  Instead, the values on the stack should be the
first two items in an nlr_buf_t: the prev pointer and the ret_val pointer.
This is all that is needed and is what the rest of the native emitter
expects is on the stack.

This patch is essentially an optimisation.  Behaviour is unchanged,
although the stack layout for native exception handling now makes more
sense.
2018-08-06 14:44:33 +10:00
Damien George 3bef7bd782 py/emitnative: Fix native locals stack to start at correct location.
A native function allocates space on its C stack for mp_code_state_t,
followed by its Python stack, then its locals.  This patch makes sure that
the native function actually starts at the start of its Python stack,
rather than at the start of mp_code_state_t (which didn't lead to any
issues so far because the mp_code_state_t is unused after the native
function sets itself up).
2018-08-04 22:41:35 +10:00
Damien George 1c0bd46d1d py/asmx86: Use generic emit function to simplify cmp emit function. 2018-08-04 22:26:14 +10:00
Damien George 10830059c5 py/emitnative: Fix x86 native zero checks by comparing full word.
On x86 archs (both 32 and 64 bit) a bool return value only sets the 8-bit
al register, and the higher bits of the ax register have an undefined
value.  When testing the return value of such cases it is required to just
test al for zero/non-zero.  On the other hand, checking for truth or
zero/non-zero on an integer return value requires checking all bits of the
register.  These two cases must be distinguished and handled correctly in
generated native code.  This patch makes sure of this.

For other supported native archs (ARM, Thumb2, Xtensa) there is no such
distinction and this patch does not change anything for them.
2018-08-04 22:03:49 +10:00
Damien George 4b1e8bdebd py/emitnative: Factor common code for native jump helper. 2018-08-04 21:45:24 +10:00