Skip to content
Snippets Groups Projects
Select Git revision
  • dualcore
  • ch3/leds
  • wip-bootstrap default
  • ch3/time
  • master
5 results

vm.c

Blame
    • Damien George's avatar
      66ae8c9f
      py: Tidy up variables in VM, probably fixes subtle bugs. · 66ae8c9f
      Damien George authored
      Things get tricky when using the nlr code to catch exceptions.  Need to
      ensure that the variables (stack layout) in the exception handler are
      the same as in the bit protected by the exception handler.
      
      Prior to this patch there were a few bugs.  1) The constant
      mp_const_MemoryError_obj was being preloaded to a specific location on
      the stack at the start of the function.  But this location on the stack
      was being overwritten in the opcode loop (since it didn't think that
      variable would ever be referenced again), and so when an exception
      occurred, the variable holding the address of MemoryError was corrupt.
      2) The FOR_ITER opcode detection in the exception handler used sp, which
      may or may not contain the right value coming out of the main opcode
      loop.
      
      With this patch there is a clear separation of variables used in the
      opcode loop and in the exception handler (should fix issue (2) above).
      Furthermore, nlr_raise is no longer used in the opcode loop.  Instead,
      it jumps directly into the exception handler.  This tells the C compiler
      more about the possible code flow, and means that it should have the
      same stack layout for the exception handler.  This should fix issue (1)
      above.  Indeed, the generated (ARM) assembler has been checked explicitly,
      and with 'goto exception_handler', the problem with &MemoryError is
      fixed.
      
      This may now fix problems with rge-sm, and probably many other subtle
      bugs yet to show themselves.  Incidentally, rge-sm now passes on
      pyboard (with a reduced range of integration)!
      
      Main lesson: nlr is tricky.  Don't use nlr_push unless you know what you
      are doing!  Luckily, it's not used in many places.  Using nlr_raise/jump
      is fine.
      66ae8c9f
      History
      py: Tidy up variables in VM, probably fixes subtle bugs.
      Damien George authored
      Things get tricky when using the nlr code to catch exceptions.  Need to
      ensure that the variables (stack layout) in the exception handler are
      the same as in the bit protected by the exception handler.
      
      Prior to this patch there were a few bugs.  1) The constant
      mp_const_MemoryError_obj was being preloaded to a specific location on
      the stack at the start of the function.  But this location on the stack
      was being overwritten in the opcode loop (since it didn't think that
      variable would ever be referenced again), and so when an exception
      occurred, the variable holding the address of MemoryError was corrupt.
      2) The FOR_ITER opcode detection in the exception handler used sp, which
      may or may not contain the right value coming out of the main opcode
      loop.
      
      With this patch there is a clear separation of variables used in the
      opcode loop and in the exception handler (should fix issue (2) above).
      Furthermore, nlr_raise is no longer used in the opcode loop.  Instead,
      it jumps directly into the exception handler.  This tells the C compiler
      more about the possible code flow, and means that it should have the
      same stack layout for the exception handler.  This should fix issue (1)
      above.  Indeed, the generated (ARM) assembler has been checked explicitly,
      and with 'goto exception_handler', the problem with &MemoryError is
      fixed.
      
      This may now fix problems with rge-sm, and probably many other subtle
      bugs yet to show themselves.  Incidentally, rge-sm now passes on
      pyboard (with a reduced range of integration)!
      
      Main lesson: nlr is tricky.  Don't use nlr_push unless you know what you
      are doing!  Luckily, it's not used in many places.  Using nlr_raise/jump
      is fine.