diff options
-rw-r--r-- | py/compile.c | 2 | ||||
-rw-r--r-- | py/vm.c | 9 | ||||
-rw-r--r-- | stmhal/boards/stm32f4xx-af.csv | 2 | ||||
-rw-r--r-- | tests/basics/for_break.py | 12 | ||||
-rw-r--r-- | tests/basics/for_return.py | 7 | ||||
-rw-r--r-- | tests/micropython/heapalloc.py | 26 | ||||
-rwxr-xr-x | tests/run-tests | 15 |
7 files changed, 62 insertions, 11 deletions
diff --git a/py/compile.c b/py/compile.c index c90772a7e3..1f0d90570e 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1745,7 +1745,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { // And, if the loop never runs, the loop variable should never be assigned void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var, mp_parse_node_t pn_start, mp_parse_node_t pn_end, mp_parse_node_t pn_step, mp_parse_node_t pn_body, mp_parse_node_t pn_else) { START_BREAK_CONTINUE_BLOCK - comp->break_label |= MP_EMIT_BREAK_FROM_FOR; + // note that we don't need to pop anything when breaking from an optimise for loop uint top_label = comp_next_label(comp); uint entry_label = comp_next_label(comp); @@ -44,7 +44,7 @@ // With these macros you can tune the maximum number of function state bytes // that will be allocated on the stack. Any function that needs more // than this will use the heap. -#define VM_MAX_STATE_ON_STACK (40) +#define VM_MAX_STATE_ON_STACK (10 * sizeof(machine_uint_t)) #define DETECT_VM_STACK_OVERFLOW (0) #if 0 @@ -160,8 +160,8 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, #if DETECT_VM_STACK_OVERFLOW if (vm_return_kind == MP_VM_RETURN_NORMAL) { - if (code_state->sp != code_state->state) { - printf("Stack misalign: %d\n", code_state->sp - code_state->state); + if (code_state->sp < code_state->state) { + printf("VM stack underflow: " INT_FMT "\n", code_state->sp - code_state->state); assert(0); } } @@ -178,7 +178,7 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, } } if (overflow) { - printf("VM stack overflow state=%p n_state+1=%u\n", code_state->state, n_state); + printf("VM stack overflow state=%p n_state+1=" UINT_FMT "\n", code_state->state, n_state); assert(0); } } @@ -203,6 +203,7 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, assert(0); *ret = mp_const_none; ret_kind = MP_VM_RETURN_NORMAL; + break; } // free the state if it was allocated on the heap diff --git a/stmhal/boards/stm32f4xx-af.csv b/stmhal/boards/stm32f4xx-af.csv index 5746ac8cc9..466be06002 100644 --- a/stmhal/boards/stm32f4xx-af.csv +++ b/stmhal/boards/stm32f4xx-af.csv @@ -1,4 +1,4 @@ -Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15 +Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15, ,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11,I2C1/2/3,SPI1/SPI2/I2S2/I2S2ext,SPI3/I2Sext/I2S3,USART1/2/3/I2S3ext,UART4/5/USART6,CAN1/CAN2/TIM12/13/14,OTG_FS/OTG_HS,ETH,FSMC/SDIO/OTG_FS,DCMI,,,ADC PortA,PA0,,TIM2_CH1_ETR,TIM5_CH1,TIM8_ETR,,,,USART2_CTS,UART4_TX,,,ETH_MII_CRS,,,,EVENTOUT,ADC123_IN0 PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,UART4_RX,,,ETH_MII_RX_CLK/ETH_RMII__REF_CLK,,,,EVENTOUT,ADC123_IN1 diff --git a/tests/basics/for_break.py b/tests/basics/for_break.py index fa8dabd150..f8bb0578e2 100644 --- a/tests/basics/for_break.py +++ b/tests/basics/for_break.py @@ -13,3 +13,15 @@ def foo(): i -= 1 foo() + +# break from within nested for loop +def bar(): + l = [1, 2, 3] + for e1 in l: + print(e1) + for e2 in l: + print(e1, e2) + if e2 == 2: + break + +bar() diff --git a/tests/basics/for_return.py b/tests/basics/for_return.py new file mode 100644 index 0000000000..0441352ad9 --- /dev/null +++ b/tests/basics/for_return.py @@ -0,0 +1,7 @@ +# test returning from within a for loop + +def f(): + for i in [1, 2, 3]: + return i + +print(f()) diff --git a/tests/micropython/heapalloc.py b/tests/micropython/heapalloc.py new file mode 100644 index 0000000000..c62428a084 --- /dev/null +++ b/tests/micropython/heapalloc.py @@ -0,0 +1,26 @@ +# check that we can do certain things without allocating heap memory + +import gc + +def f(a): + print(a) + +def g(a, b=2): + print(a, b) + +global_var = 1 + +def h(): + global global_var + global_var = 2 # set an existing global variable + for i in range(2): # for loop + f(i) # function call + f(i * 2 + 1) # binary operation with small ints + f(a=i) # keyword arguments + g(i) # default arg (second one) + g(i, i) # 2 args + +# call h with heap allocation disabled +gc.disable() +h() +gc.enable() diff --git a/tests/run-tests b/tests/run-tests index 102655abea..1e6dd50538 100755 --- a/tests/run-tests +++ b/tests/run-tests @@ -111,6 +111,7 @@ def run_tests(pyb, tests): def main(): cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.') cmd_parser.add_argument('--pyboard', action='store_true', help='run the tests on the pyboard') + cmd_parser.add_argument('-d', '--test-dirs', nargs='*', help='input test directories (if no files given)') cmd_parser.add_argument('files', nargs='*', help='input test files') args = cmd_parser.parse_args() @@ -122,12 +123,16 @@ def main(): pyb = None if len(args.files) == 0: - if pyb is None: - # run PC tests - test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc') + if args.test_dirs is None: + if pyb is None: + # run PC tests + test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc') + else: + # run pyboard tests + test_dirs = ('basics', 'float', 'pyb', 'pybnative', 'inlineasm') else: - # run pyboard tests - test_dirs = ('basics', 'float', 'pyb', 'pybnative', 'inlineasm') + # run tests from these directories + test_dirs = args.test_dirs tests = sorted(test_file for test_files in (glob('{}/*.py'.format(dir)) for dir in test_dirs) for test_file in test_files) else: # tests explicitly given |