Skip to content
Snippets Groups Projects
  1. Oct 01, 2018
    • Damien George's avatar
      py/emitnative: Implement yield and yield-from in native emitter. · cc2bd63c
      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.
      cc2bd63c
  2. Sep 15, 2018
    • Damien George's avatar
      py: Make viper functions have the same entry signature as native. · 43f1848b
      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.
      43f1848b
  3. Sep 13, 2018
    • Damien George's avatar
      py: Fix native functions so they run with their correct globals context. · 4f3d9429
      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.
      4f3d9429
  4. Sep 04, 2018
  5. Aug 17, 2018
  6. Aug 16, 2018
    • Damien George's avatar
      py/emitnative: Optimise and improve exception handling in native code. · a3de7764
      Damien George authored
      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.
      a3de7764
  7. May 04, 2018
  8. Apr 10, 2018
    • Damien George's avatar
      py: Refactor how native emitter code is compiled with a file per arch. · ef12a4bd
      Damien George authored
      Instead of emitnative.c having configuration code for each supported
      architecture, and then compiling this file multiple times with different
      macros defined, this patch adds a file per architecture with the necessary
      code to configure the native emitter.  These files then #include the
      emitnative.c file.
      
      This simplifies emitnative.c (which is already very large), and simplifies
      the build system because emitnative.c no longer needs special handling for
      compilation and qstr extraction.
      ef12a4bd
Loading