From dd0dee3afcfbabf6b1efe36136b5506857e76aef Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Tue, 3 Jun 2014 01:01:39 +0300 Subject: [PATCH 01/11] unix: Properly print script filename in case of error. --- unix/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/main.c b/unix/main.c index c9f38d6139..992ea1fec5 100644 --- a/unix/main.c +++ b/unix/main.c @@ -355,7 +355,7 @@ int main(int argc, char **argv) { } else { char *basedir = realpath(argv[a], NULL); if (basedir == NULL) { - fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[1], errno); + fprintf(stderr, "%s: can't open file '%s': [Errno %d] ", argv[0], argv[a], errno); perror(""); // CPython exits with 2 in such case ret = 2; From a4ac5b9f05367c66eb22ae3a0274968db697420c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Tue, 3 Jun 2014 01:24:29 +0300 Subject: [PATCH 02/11] showbc: Make sure it's possible to trace MAKE_FUNCTION arg to actual bytecode. --- py/bc.h | 2 +- py/emitglue.c | 2 +- py/showbc.c | 13 +++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/py/bc.h b/py/bc.h index 6c604fe1c0..915a0f269e 100644 --- a/py/bc.h +++ b/py/bc.h @@ -51,7 +51,7 @@ typedef struct _mp_code_state { mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret); mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_obj_t inject_exc); -void mp_bytecode_print(const byte *code, int len); +void mp_bytecode_print(const void *descr, const byte *code, int len); void mp_bytecode_print2(const byte *code, int len); // Helper macros to access pointer with least significant bit holding a flag diff --git a/py/emitglue.c b/py/emitglue.c index 528c3bd36c..fa62ace6df 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -81,7 +81,7 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint #endif #if MICROPY_DEBUG_PRINTERS if (mp_verbose_flag > 0) { - mp_bytecode_print(code, len); + mp_bytecode_print(rc, code, len); } #endif } diff --git a/py/showbc.c b/py/showbc.c index 8169368410..5a4e918cd5 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -56,7 +56,7 @@ void mp_bytecode_print2(const byte *ip, int len); -void mp_bytecode_print(const byte *ip, int len) { +void mp_bytecode_print(const void *descr, const byte *ip, int len) { const byte *ip_start = ip; // get code info size @@ -66,7 +66,8 @@ void mp_bytecode_print(const byte *ip, int len) { qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); - printf("File %s, code block '%s' (%d bytes)\n", qstr_str(source_file), qstr_str(block_name), len); + printf("File %s, code block '%s' (descriptor: %p, bytecode @%p %d bytes)\n", + qstr_str(source_file), qstr_str(block_name), descr, code_info, len); // bytecode prelude: state size and exception stack size; 16 bit uints { @@ -434,25 +435,25 @@ void mp_bytecode_print2(const byte *ip, int len) { case MP_BC_MAKE_FUNCTION: DECODE_PTR; - printf("MAKE_FUNCTION " UINT_FMT, unum); + printf("MAKE_FUNCTION %p", (void*)unum); break; case MP_BC_MAKE_FUNCTION_DEFARGS: DECODE_PTR; - printf("MAKE_FUNCTION_DEFARGS " UINT_FMT, unum); + printf("MAKE_FUNCTION_DEFARGS %p", (void*)unum); break; case MP_BC_MAKE_CLOSURE: { DECODE_PTR; machine_uint_t n_closed_over = *ip++; - printf("MAKE_CLOSURE " UINT_FMT " " UINT_FMT, unum, n_closed_over); + printf("MAKE_CLOSURE %p " UINT_FMT, (void*)unum, n_closed_over); break; } case MP_BC_MAKE_CLOSURE_DEFARGS: { DECODE_PTR; machine_uint_t n_closed_over = *ip++; - printf("MAKE_CLOSURE_DEFARGS " UINT_FMT " " UINT_FMT, unum, n_closed_over); + printf("MAKE_CLOSURE_DEFARGS %p " UINT_FMT, (void*)unum, n_closed_over); break; } From f753971e5dc6af3ae399400a1258ca67279d8ea0 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Tue, 3 Jun 2014 01:38:01 +0300 Subject: [PATCH 03/11] showbc: Make micropython -v also dump bytecode in hex form. --- py/emitglue.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/py/emitglue.c b/py/emitglue.c index fa62ace6df..a89ef6766a 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -71,16 +71,16 @@ void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, byte *code, uint len, uint DEBUG_printf(" %s", qstr_str(arg_names[i])); } DEBUG_printf("\n"); - for (int i = 0; i < 128 && i < len; i++) { - if (i > 0 && i % 16 == 0) { - DEBUG_printf("\n"); - } - DEBUG_printf(" %02x", code[i]); - } - DEBUG_printf("\n"); #endif #if MICROPY_DEBUG_PRINTERS if (mp_verbose_flag > 0) { + for (int i = 0; i < 128 && i < len; i++) { + if (i > 0 && i % 16 == 0) { + printf("\n"); + } + printf(" %02x", code[i]); + } + printf("\n"); mp_bytecode_print(rc, code, len); } #endif From 4e0573e5cff203d6eb28d1f8a0530eb14fe5beaa Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Mon, 2 Jun 2014 23:04:41 -0700 Subject: [PATCH 04/11] Add missing commas to stm32f4xx-af.csv --- stmhal/boards/stm32f4xx-af.csv | 234 ++++++++++++++++----------------- 1 file changed, 117 insertions(+), 117 deletions(-) diff --git a/stmhal/boards/stm32f4xx-af.csv b/stmhal/boards/stm32f4xx-af.csv index 466be06002..b9a308a82c 100644 --- a/stmhal/boards/stm32f4xx-af.csv +++ b/stmhal/boards/stm32f4xx-af.csv @@ -3,86 +3,86 @@ Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15, 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 PortA,PA2,,TIM2_CH3,TIM5_CH3,TIM9_CH1,,,,USART2_TX,,,,ETH_MDIO,,,,EVENTOUT,ADC123_IN2 -PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,,USART2_RX,,,OTG_HS_ULPI_D0,ETH_MII_COL,,,,EVENTOUTADC123_IN3 +PortA,PA3,,TIM2_CH4,TIM5_CH4,TIM9_CH2,,,,USART2_RX,,,OTG_HS_ULPI_D0,ETH_MII_COL,,,,EVENTOUT,ADC123_IN3 PortA,PA4,,,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,USART2_CK,,,,,OTG_HS_SOF,DCMI_HSYNC,,EVENTOUT,ADC12_IN4 PortA,PA5,,TIM2_CH1_ETR,,TIM8_CH1N,,SPI1_SCK,,,,,OTG_HS_ULPI_CK,,,,,EVENTOUT,ADC12_IN5 PortA,PA6,,TIM1_BKIN,TIM3_CH1,TIM8_BKIN,,SPI1_MISO,,,,TIM13_CH1,,,,DCMI_PIXCK,,EVENTOUT,ADC12_IN6 PortA,PA7,,TIM1_CH1N,TIM3_CH2,TIM8_CH1N,,SPI1_MOSI,,,,TIM14_CH1,,ETH_MII_RX_DV/ETH_RMII_CRS_DV,,,,EVENTOUT,ADC12_IN7 -PortA,PA8,MCO1,TIM1_CH1,,,I2C3_SCL,,,USART1_CK,,,OTG_FS_SOF,,,,,EVENTOUT -PortA,PA9,,TIM1_CH2,,,I2C3_SMBA,,,USART1_TX,,,,,,DCMI_D0,,EVENTOUT -PortA,PA10,,TIM1_CH3,,,,,,USART1_RX,,,OTG_FS_ID,,,DCMI_D1,,EVENTOUT -PortA,PA11,,TIM1_CH4,,,,,,USART1_CTS,,CAN1_RX,OTG_FS_DM,,,,,EVENTOUT -PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,,CAN1_TX,OTG_FS_DP,,,,,EVENTOUT -PortA,PA13,JTMS-SWDIO,,,,,,,,,,,,,,,EVENTOUT -PortA,PA14,JTCK-SWCLK,,,,,,,,,,,,,,,EVENTOUT -PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,,,,,,,,,EVENTOUT +PortA,PA8,MCO1,TIM1_CH1,,,I2C3_SCL,,,USART1_CK,,,OTG_FS_SOF,,,,,EVENTOUT, +PortA,PA9,,TIM1_CH2,,,I2C3_SMBA,,,USART1_TX,,,,,,DCMI_D0,,EVENTOUT, +PortA,PA10,,TIM1_CH3,,,,,,USART1_RX,,,OTG_FS_ID,,,DCMI_D1,,EVENTOUT, +PortA,PA11,,TIM1_CH4,,,,,,USART1_CTS,,CAN1_RX,OTG_FS_DM,,,,,EVENTOUT, +PortA,PA12,,TIM1_ETR,,,,,,USART1_RTS,,CAN1_TX,OTG_FS_DP,,,,,EVENTOUT, +PortA,PA13,JTMS-SWDIO,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA14,JTCK-SWCLK,,,,,,,,,,,,,,,EVENTOUT, +PortA,PA15,JTDI,TIM2_CH1/TIM2_ETR,,,,SPI1_NSS,SPI3_NSS/I2S3_WS,,,,,,,,,EVENTOUT, PortB,PB0,,TIM1_CH2N,TIM3_CH3,TIM8_CH2N,,,,,,,OTG_HS_ULPI_D1,ETH_MII_RXD2,,,,EVENTOUT,ADC12_IN8 PortB,PB1,,TIM1_CH3N,TIM3_CH4,TIM8_CH3N,,,,,,,OTG_HS_ULPI_D2,ETH_MII_RXD3,,,,EVENTOUT,ADC12_IN9 -PortB,PB2,,,,,,,,,,,,,,,,EVENTOUT -PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK,SPI3_SCK/I2S3_CK,,,,,,,,,EVENTOUT -PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,I2S3ext_SD,,,,,,,,EVENTOUT -PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI,SPI3_MOSI/I2S3_SD,,,CAN2_RX,OTG_HS_ULPI_D7,ETH_PPS_OUT,,DCMI_D10,,EVENTOUT -PortB,PB6,,,TIM4_CH1,,I2C1_SCL,,,USART1_TX,,CAN2_TX,,,,DCMI_D5,,EVENTOUT -PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,,,,,FSMC_NL,DCMI_VSYNC,,EVENTOUT -PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,,ETH_MII_TXD3,SDIO_D4,DCMI_D6,,EVENTOUT -PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,,,,CAN1_TX,,,SDIO_D5,DCMI_D7,,EVENTOUT -PortB,PB10,,TIM2_CH3,,,I2C2_SCL,SPI2_SCK/I2S2_CK,,USART3_TX,,,OTG_HS_ULPI_D3,ETH_MII_RX_ER,,,,EVENTOUT -PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,,,OTG_HS_ULPI_D4,ETH_MII_TX_EN/ETH_RMII_TX_EN,,,,EVENTOUT -PortB,PB12,,TIM1_BKIN,,,I2C2_SMBA,SPI2_NSS/I2S2_WS,,USART3_CK,,CAN2_RX,OTG_HS_ULPI_D5,ETH_MII_TXD0/ETH_RMII_TXD0,OTG_HS_ID,,,EVENTOUT -PortB,PB13,,TIM1_CH1N,,,,SPI2_SCK/I2S2_CK,,USART3_CTS,,CAN2_TX,OTG_HS_ULPI_D6,ETH_MII_TXD1/ETH_RMII_TXD1,,,,EVENTOUT -PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,I2S2ext_SD,USART3_RTS,,TIM12_CH1,,,OTG_HS_DM,,,EVENTOUT -PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,,,OTG_HS_DP,,,EVENTOUT +PortB,PB2,,,,,,,,,,,,,,,,EVENTOUT, +PortB,PB3,JTDO/TRACESWO,TIM2_CH2,,,,SPI1_SCK,SPI3_SCK/I2S3_CK,,,,,,,,,EVENTOUT, +PortB,PB4,NJTRST,,TIM3_CH1,,,SPI1_MISO,SPI3_MISO,I2S3ext_SD,,,,,,,,EVENTOUT, +PortB,PB5,,,TIM3_CH2,,I2C1_SMBA,SPI1_MOSI,SPI3_MOSI/I2S3_SD,,,CAN2_RX,OTG_HS_ULPI_D7,ETH_PPS_OUT,,DCMI_D10,,EVENTOUT, +PortB,PB6,,,TIM4_CH1,,I2C1_SCL,,,USART1_TX,,CAN2_TX,,,,DCMI_D5,,EVENTOUT, +PortB,PB7,,,TIM4_CH2,,I2C1_SDA,,,USART1_RX,,,,,FSMC_NL,DCMI_VSYNC,,EVENTOUT, +PortB,PB8,,,TIM4_CH3,TIM10_CH1,I2C1_SCL,,,,,CAN1_RX,,ETH_MII_TXD3,SDIO_D4,DCMI_D6,,EVENTOUT, +PortB,PB9,,,TIM4_CH4,TIM11_CH1,I2C1_SDA,SPI2_NSS/I2S2_WS,,,,CAN1_TX,,,SDIO_D5,DCMI_D7,,EVENTOUT, +PortB,PB10,,TIM2_CH3,,,I2C2_SCL,SPI2_SCK/I2S2_CK,,USART3_TX,,,OTG_HS_ULPI_D3,ETH_MII_RX_ER,,,,EVENTOUT, +PortB,PB11,,TIM2_CH4,,,I2C2_SDA,,,USART3_RX,,,OTG_HS_ULPI_D4,ETH_MII_TX_EN/ETH_RMII_TX_EN,,,,EVENTOUT, +PortB,PB12,,TIM1_BKIN,,,I2C2_SMBA,SPI2_NSS/I2S2_WS,,USART3_CK,,CAN2_RX,OTG_HS_ULPI_D5,ETH_MII_TXD0/ETH_RMII_TXD0,OTG_HS_ID,,,EVENTOUT, +PortB,PB13,,TIM1_CH1N,,,,SPI2_SCK/I2S2_CK,,USART3_CTS,,CAN2_TX,OTG_HS_ULPI_D6,ETH_MII_TXD1/ETH_RMII_TXD1,,,,EVENTOUT, +PortB,PB14,,TIM1_CH2N,,TIM8_CH2N,,SPI2_MISO,I2S2ext_SD,USART3_RTS,,TIM12_CH1,,,OTG_HS_DM,,,EVENTOUT, +PortB,PB15,RTC_REFIN,TIM1_CH3N,,TIM8_CH3N,,SPI2_MOSI/I2S2_SD,,,,TIM12_CH2,,,OTG_HS_DP,,,EVENTOUT, PortC,PC0,,,,,,,,,,,OTG_HS_ULPI_STP,,,,,EVENTOUT,ADC123_IN10 PortC,PC1,,,,,,,,,,,,ETH_MDC,,,,EVENTOUT,ADC123_IN11 PortC,PC2,,,,,,SPI2_MISO,I2S2ext_SD,,,,OTG_HS_ULPI_DIR,ETH_MII_TXD2,,,,EVENTOUT,ADC123_IN12 PortC,PC3,,,,,,SPI2_MOSI/I2S2_SD,,,,,OTG_HS_ULPI_NXT,ETH_MII_TX_CLK,,,,EVENTOUT,ADC123_IN13 PortC,PC4,,,,,,,,,,,,ETH_MII_RXD0/ETH_RMII_RXD0,,,,EVENTOUT,ADC123_IN14 PortC,PC5,,,,,,,,,,,,ETH_MII_RXD1/ETH_RMII_RXD1,,,,EVENTOUT,ADC123_IN15 -PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,,,SDIO_D6,DCMI_D0,,EVENTOUT -PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,,,SDIO_D7,DCMI_D1,,EVENTOUT -PortC,PC8,,,TIM3_CH3,TIM8_CH3,,,,,USART6_CK,,,,SDIO_D0,DCMI_D2,,EVENTOUT -PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,,,,,,SDIO_D1,DCMI_D3,,EVENTOUT -PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,,,,SDIO_D2,DCMI_D8,,EVENTOUT -PortC,PC11,,,,,,I2S3ext_SD,SPI3_MISO,USART3_RX,UART4_RX,,,,SDIO_D3,DCMI_D4,,EVENTOUT -PortC,PC12,,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDIO_CK,DCMI_D9,,EVENTOUT -PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT -PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT -PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT -PortD,PD0,,,,,,,,,,CAN1_RX,,,FSMC_D2,,,EVENTOUT -PortD,PD1,,,,,,,,,,CAN1_TX,,,FSMC_D3,,,EVENTOUT -PortD,PD2,,,TIM3_ETR,,,,,,UART5_RX,,,,SDIO_CMD,DCMI_D11,,EVENTOUT -PortD,PD3,,,,,,,,USART2_CTS,,,,,FSMC_CLK,,,EVENTOUT -PortD,PD4,,,,,,,,USART2_RTS,,,,,FSMC_NOE,,,EVENTOUT -PortD,PD5,,,,,,,,USART2_TX,,,,,FSMC_NWE,,,EVENTOUT -PortD,PD6,,,,,,,,USART2_RX,,,,,FSMC_NWAIT,,,EVENTOUT -PortD,PD7,,,,,,,,USART2_CK,,,,,FSMC_NE1/FSMC_NCE2,,,EVENTOUT -PortD,PD8,,,,,,,,USART3_TX,,,,,FSMC_D13,,,EVENTOUT -PortD,PD9,,,,,,,,USART3_RX,,,,,FSMC_D14,,,EVENTOUT -PortD,PD10,,,,,,,,USART3_CK,,,,,FSMC_D15,,,EVENTOUT -PortD,PD11,,,,,,,,USART3_CTS,,,,,FSMC_A16,,,EVENTOUT -PortD,PD12,,,TIM4_CH1,,,,,USART3_RTS,,,,,FSMC_A17,,,EVENTOUT -PortD,PD13,,,TIM4_CH2,,,,,,,,,,FSMC_A18,,,EVENTOUT -PortD,PD14,,,TIM4_CH3,,,,,,,,,,FSMC_D0,,,EVENTOUT -PortD,PD15,,,TIM4_CH4,,,,,,,,,,FSMC_D1,,,EVENTOUT -PortE,PE0,,,TIM4_ETR,,,,,,,,,,FSMC_NBL0,DCMI_D2,,EVENTOUT -PortE,PE1,,,,,,,,,,,,,FSMC_NBL1,DCMI_D3,,EVENTOUT -PortE,PE2,TRACECLK,,,,,,,,,,,ETH_MII_TXD3,FSMC_A23,,,EVENTOUT -PortE,PE3,TRACED0,,,,,,,,,,,,FSMC_A19,,,EVENTOUT -PortE,PE4,TRACED1,,,,,,,,,,,,FSMC_A20,DCMI_D4,,EVENTOUT -PortE,PE5,TRACED2,,,TIM9_CH1,,,,,,,,,FSMC_A21,DCMI_D6,,EVENTOUT -PortE,PE6,TRACED3,,,TIM9_CH2,,,,,,,,,FSMC_A22,DCMI_D7,,EVENTOUT -PortE,PE7,,TIM1_ETR,,,,,,,,,,,FSMC_D4,,,EVENTOUT -PortE,PE8,,TIM1_CH1N,,,,,,,,,,,FSMC_D5,,,EVENTOUT -PortE,PE9,,TIM1_CH1,,,,,,,,,,,FSMC_D6,,,EVENTOUT -PortE,PE10,,TIM1_CH2N,,,,,,,,,,,FSMC_D7,,,EVENTOUT -PortE,PE11,,TIM1_CH2,,,,,,,,,,,FSMC_D8,,,EVENTOUT -PortE,PE12,,TIM1_CH3N,,,,,,,,,,,FSMC_D9,,,EVENTOUT -PortE,PE13,,TIM1_CH3,,,,,,,,,,,FSMC_D10,,,EVENTOUT -PortE,PE14,,TIM1_CH4,,,,,,,,,,,FSMC_D11,,,EVENTOUT -PortE,PE15,,TIM1_BKIN,,,,,,,,,,,FSMC_D12,,,EVENTOUT -PortF,PF0,,,,,I2C2_SDA,,,,,,,,FSMC_A0,,,EVENTOUT -PortF,PF1,,,,,I2C2_SCL,,,,,,,,FSMC_A1,,,EVENTOUT -PortF,PF2,,,,,I2C2_SMBA,,,,,,,,FSMC_A2,,,EVENTOUT +PortC,PC6,,,TIM3_CH1,TIM8_CH1,,I2S2_MCK,,,USART6_TX,,,,SDIO_D6,DCMI_D0,,EVENTOUT, +PortC,PC7,,,TIM3_CH2,TIM8_CH2,,,I2S3_MCK,,USART6_RX,,,,SDIO_D7,DCMI_D1,,EVENTOUT, +PortC,PC8,,,TIM3_CH3,TIM8_CH3,,,,,USART6_CK,,,,SDIO_D0,DCMI_D2,,EVENTOUT, +PortC,PC9,MCO2,,TIM3_CH4,TIM8_CH4,I2C3_SDA,I2S_CKIN,,,,,,,SDIO_D1,DCMI_D3,,EVENTOUT, +PortC,PC10,,,,,,,SPI3_SCK/I2S3_CK,USART3_TX,UART4_TX,,,,SDIO_D2,DCMI_D8,,EVENTOUT, +PortC,PC11,,,,,,I2S3ext_SD,SPI3_MISO,USART3_RX,UART4_RX,,,,SDIO_D3,DCMI_D4,,EVENTOUT, +PortC,PC12,,,,,,,SPI3_MOSI/I2S3_SD,USART3_CK,UART5_TX,,,,SDIO_CK,DCMI_D9,,EVENTOUT, +PortC,PC13,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC14,,,,,,,,,,,,,,,,EVENTOUT, +PortC,PC15,,,,,,,,,,,,,,,,EVENTOUT, +PortD,PD0,,,,,,,,,,CAN1_RX,,,FSMC_D2,,,EVENTOUT, +PortD,PD1,,,,,,,,,,CAN1_TX,,,FSMC_D3,,,EVENTOUT, +PortD,PD2,,,TIM3_ETR,,,,,,UART5_RX,,,,SDIO_CMD,DCMI_D11,,EVENTOUT, +PortD,PD3,,,,,,,,USART2_CTS,,,,,FSMC_CLK,,,EVENTOUT, +PortD,PD4,,,,,,,,USART2_RTS,,,,,FSMC_NOE,,,EVENTOUT, +PortD,PD5,,,,,,,,USART2_TX,,,,,FSMC_NWE,,,EVENTOUT, +PortD,PD6,,,,,,,,USART2_RX,,,,,FSMC_NWAIT,,,EVENTOUT, +PortD,PD7,,,,,,,,USART2_CK,,,,,FSMC_NE1/FSMC_NCE2,,,EVENTOUT, +PortD,PD8,,,,,,,,USART3_TX,,,,,FSMC_D13,,,EVENTOUT, +PortD,PD9,,,,,,,,USART3_RX,,,,,FSMC_D14,,,EVENTOUT, +PortD,PD10,,,,,,,,USART3_CK,,,,,FSMC_D15,,,EVENTOUT, +PortD,PD11,,,,,,,,USART3_CTS,,,,,FSMC_A16,,,EVENTOUT, +PortD,PD12,,,TIM4_CH1,,,,,USART3_RTS,,,,,FSMC_A17,,,EVENTOUT, +PortD,PD13,,,TIM4_CH2,,,,,,,,,,FSMC_A18,,,EVENTOUT, +PortD,PD14,,,TIM4_CH3,,,,,,,,,,FSMC_D0,,,EVENTOUT, +PortD,PD15,,,TIM4_CH4,,,,,,,,,,FSMC_D1,,,EVENTOUT, +PortE,PE0,,,TIM4_ETR,,,,,,,,,,FSMC_NBL0,DCMI_D2,,EVENTOUT, +PortE,PE1,,,,,,,,,,,,,FSMC_NBL1,DCMI_D3,,EVENTOUT, +PortE,PE2,TRACECLK,,,,,,,,,,,ETH_MII_TXD3,FSMC_A23,,,EVENTOUT, +PortE,PE3,TRACED0,,,,,,,,,,,,FSMC_A19,,,EVENTOUT, +PortE,PE4,TRACED1,,,,,,,,,,,,FSMC_A20,DCMI_D4,,EVENTOUT, +PortE,PE5,TRACED2,,,TIM9_CH1,,,,,,,,,FSMC_A21,DCMI_D6,,EVENTOUT, +PortE,PE6,TRACED3,,,TIM9_CH2,,,,,,,,,FSMC_A22,DCMI_D7,,EVENTOUT, +PortE,PE7,,TIM1_ETR,,,,,,,,,,,FSMC_D4,,,EVENTOUT, +PortE,PE8,,TIM1_CH1N,,,,,,,,,,,FSMC_D5,,,EVENTOUT, +PortE,PE9,,TIM1_CH1,,,,,,,,,,,FSMC_D6,,,EVENTOUT, +PortE,PE10,,TIM1_CH2N,,,,,,,,,,,FSMC_D7,,,EVENTOUT, +PortE,PE11,,TIM1_CH2,,,,,,,,,,,FSMC_D8,,,EVENTOUT, +PortE,PE12,,TIM1_CH3N,,,,,,,,,,,FSMC_D9,,,EVENTOUT, +PortE,PE13,,TIM1_CH3,,,,,,,,,,,FSMC_D10,,,EVENTOUT, +PortE,PE14,,TIM1_CH4,,,,,,,,,,,FSMC_D11,,,EVENTOUT, +PortE,PE15,,TIM1_BKIN,,,,,,,,,,,FSMC_D12,,,EVENTOUT, +PortF,PF0,,,,,I2C2_SDA,,,,,,,,FSMC_A0,,,EVENTOUT, +PortF,PF1,,,,,I2C2_SCL,,,,,,,,FSMC_A1,,,EVENTOUT, +PortF,PF2,,,,,I2C2_SMBA,,,,,,,,FSMC_A2,,,EVENTOUT, PortF,PF3,,,,,,,,,,,,,FSMC_A3,,,EVENTOUT,ADC3_IN9 PortF,PF4,,,,,,,,,,,,,FSMC_A4,,,EVENTOUT,ADC3_IN14 PortF,PF5,,,,,,,,,,,,,FSMC_A5,,,EVENTOUT,ADC3_IN15 @@ -91,52 +91,52 @@ PortF,PF7,,,,TIM11_CH1,,,,,,,,,FSMC_NREG,,,EVENTOUT,ADC3_IN5 PortF,PF8,,,,,,,,,,TIM13_CH1,,,FSMC_NIOWR,,,EVENTOUT,ADC3_IN6 PortF,PF9,,,,,,,,,,TIM14_CH1,,,FSMC_CD,,,EVENTOUT,ADC3_IN7 PortF,PF10,,,,,,,,,,,,,FSMC_INTR,,,EVENTOUT,ADC3_IN8 -PortF,PF11,,,,,,,,,,,,,,DCMI_D12,,EVENTOUT -PortF,PF12,,,,,,,,,,,,,FSMC_A6,,,EVENTOUT -PortF,PF13,,,,,,,,,,,,,FSMC_A7,,,EVENTOUT -PortF,PF14,,,,,,,,,,,,,FSMC_A8,,,EVENTOUT -PortF,PF15,,,,,,,,,,,,,FSMC_A9,,,EVENTOUT -PortG,PG0,,,,,,,,,,,,,FSMC_A10,,,EVENTOUT -PortG,PG1,,,,,,,,,,,,,FSMC_A11,,,EVENTOUT -PortG,PG2,,,,,,,,,,,,,FSMC_A12,,,EVENTOUT -PortG,PG3,,,,,,,,,,,,,FSMC_A13,,,EVENTOUT -PortG,PG4,,,,,,,,,,,,,FSMC_A14,,,EVENTOUT -PortG,PG5,,,,,,,,,,,,,FSMC_A15,,,EVENTOUT -PortG,PG6,,,,,,,,,,,,,FSMC_INT2,,,EVENTOUT -PortG,PG7,,,,,,,,,USART6_CK,,,,FSMC_INT3,,,EVENTOUT -PortG,PG8,,,,,,,,,USART6_RTS,,,ETH_PPS_OUT,,,,EVENTOUT -PortG,PG9,,,,,,,,,USART6_RX,,,,FSMC_NE2/FSMC_NCE3,,,EVENTOUT -PortG,PG10,,,,,,,,,,,,,FSMC_NCE4_1/FSMC_NE3,,,EVENTOUT -PortG,PG11,,,,,,,,,,,,ETH_MII_TX_EN/ETH_RMII_TX_EN,FSMC_NCE4_2,,,EVENTOUT -PortG,PG12,,,,,,,,,USART6_RTS,,,,FSMC_NE4,,,EVENTOUT -PortG,PG13,,,,,,,,,USART6_CTS,,,ETH_MII_TXD0/ETH_RMII_TXD0,FSMC_A24,,,EVENTOUT -PortG,PG14,,,,,,,,,USART6_TX,,,ETH_MII_TXD1/ETH_RMII_TXD1,FSMC_A25,,,EVENTOUT -PortG,PG15,,,,,,,,,USART6_CTS,,,,,DCMI_D13,,EVENTOUT -PortH,PH0,,,,,,,,,,,,,,,,EVENTOUT -PortH,PH1,,,,,,,,,,,,,,,,EVENTOUT -PortH,PH2,,,,,,,,,,,,ETH_MII_CRS,,,,EVENTOUT -PortH,PH3,,,,,,,,,,,,ETH_MII_COL,,,,EVENTOUT -PortH,PH4,,,,,I2C2_SCL,,,,,,OTG_HS_ULPI_NXT,,,,,EVENTOUT -PortH,PH5,,,,,I2C2_SDA,,,,,,,,,,,EVENTOUT -PortH,PH6,,,,,I2C2_SMBA,,,,,TIM12_CH1,,ETH_MII_RXD2,,,,EVENTOUT -PortH,PH7,,,,,I2C3_SCL,,,,,,,ETH_MII_RXD3,,,,EVENTOUT -PortH,PH8,,,,,I2C3_SDA,,,,,,,,,DCMI_HSYNC,,EVENTOUT -PortH,PH9,,,,,I2C3_SMBA,,,,,TIM12_CH2,,,,DCMI_D0,,EVENTOUT -PortH,PH10,,,TIM5_CH1,,,,,,,,,,,DCMI_D1,,EVENTOUT -PortH,PH11,,,TIM5_CH2,,,,,,,,,,,DCMI_D2,,EVENTOUT -PortH,PH12,,,TIM5_CH3,,,,,,,,,,,DCMI_D3,,EVENTOUT -PortH,PH13,,,,TIM8_CH1N,,,,,,CAN1_TX,,,,,,EVENTOUT -PortH,PH14,,,,TIM8_CH2N,,,,,,,,,,DCMI_D4,,EVENTOUT -PortH,PH15,,,,TIM8_CH3N,,,,,,,,,,DCMI_D11,,EVENTOUT -PortI,PI0,,,TIM5_CH4,,,SPI2_NSS/I2S2_WS,,,,,,,,DCMI_D13,,EVENTOUT -PortI,PI1,,,,,,SPI2_SCK/I2S2_CK,,,,,,,,DCMI_D8,,EVENTOUT -PortI,PI2,,,,TIM8_CH4,,SPI2_MISO,I2S2ext_SD,,,,,,,DCMI_D9,,EVENTOUT -PortI,PI3,,,,TIM8_ETR,,SPI2_MOSI/I2S2_SD,,,,,,,,DCMI_D10,,EVENTOUT -PortI,PI4,,,,TIM8_BKIN,,,,,,,,,,DCMI_D5,,EVENTOUT -PortI,PI5,,,,TIM8_CH1,,,,,,,,,,DCMI_VSYNC,,EVENTOUT -PortI,PI6,,,,TIM8_CH2,,,,,,,,,,DCMI_D6,,EVENTOUT -PortI,PI7,,,,TIM8_CH3,,,,,,,,,,DCMI_D7,,EVENTOUT -PortI,PI8,,,,,,,,,,,,,,,,EVENTOUT -PortI,PI9,,,,,,,,,,CAN1_RX,,,,,,EVENTOUT -PortI,PI10,,,,,,,,,,,,ETH_MII_RX_ER,,,,EVENTOUT -PortI,PI11,,,,,,,,,,,OTG_HS_ULPI_DIR,,,,,EVENTOUT +PortF,PF11,,,,,,,,,,,,,,DCMI_D12,,EVENTOUT, +PortF,PF12,,,,,,,,,,,,,FSMC_A6,,,EVENTOUT, +PortF,PF13,,,,,,,,,,,,,FSMC_A7,,,EVENTOUT, +PortF,PF14,,,,,,,,,,,,,FSMC_A8,,,EVENTOUT, +PortF,PF15,,,,,,,,,,,,,FSMC_A9,,,EVENTOUT, +PortG,PG0,,,,,,,,,,,,,FSMC_A10,,,EVENTOUT, +PortG,PG1,,,,,,,,,,,,,FSMC_A11,,,EVENTOUT, +PortG,PG2,,,,,,,,,,,,,FSMC_A12,,,EVENTOUT, +PortG,PG3,,,,,,,,,,,,,FSMC_A13,,,EVENTOUT, +PortG,PG4,,,,,,,,,,,,,FSMC_A14,,,EVENTOUT, +PortG,PG5,,,,,,,,,,,,,FSMC_A15,,,EVENTOUT, +PortG,PG6,,,,,,,,,,,,,FSMC_INT2,,,EVENTOUT, +PortG,PG7,,,,,,,,,USART6_CK,,,,FSMC_INT3,,,EVENTOUT, +PortG,PG8,,,,,,,,,USART6_RTS,,,ETH_PPS_OUT,,,,EVENTOUT, +PortG,PG9,,,,,,,,,USART6_RX,,,,FSMC_NE2/FSMC_NCE3,,,EVENTOUT, +PortG,PG10,,,,,,,,,,,,,FSMC_NCE4_1/FSMC_NE3,,,EVENTOUT, +PortG,PG11,,,,,,,,,,,,ETH_MII_TX_EN/ETH_RMII_TX_EN,FSMC_NCE4_2,,,EVENTOUT, +PortG,PG12,,,,,,,,,USART6_RTS,,,,FSMC_NE4,,,EVENTOUT, +PortG,PG13,,,,,,,,,USART6_CTS,,,ETH_MII_TXD0/ETH_RMII_TXD0,FSMC_A24,,,EVENTOUT, +PortG,PG14,,,,,,,,,USART6_TX,,,ETH_MII_TXD1/ETH_RMII_TXD1,FSMC_A25,,,EVENTOUT, +PortG,PG15,,,,,,,,,USART6_CTS,,,,,DCMI_D13,,EVENTOUT, +PortH,PH0,,,,,,,,,,,,,,,,EVENTOUT, +PortH,PH1,,,,,,,,,,,,,,,,EVENTOUT, +PortH,PH2,,,,,,,,,,,,ETH_MII_CRS,,,,EVENTOUT, +PortH,PH3,,,,,,,,,,,,ETH_MII_COL,,,,EVENTOUT, +PortH,PH4,,,,,I2C2_SCL,,,,,,OTG_HS_ULPI_NXT,,,,,EVENTOUT, +PortH,PH5,,,,,I2C2_SDA,,,,,,,,,,,EVENTOUT, +PortH,PH6,,,,,I2C2_SMBA,,,,,TIM12_CH1,,ETH_MII_RXD2,,,,EVENTOUT, +PortH,PH7,,,,,I2C3_SCL,,,,,,,ETH_MII_RXD3,,,,EVENTOUT, +PortH,PH8,,,,,I2C3_SDA,,,,,,,,,DCMI_HSYNC,,EVENTOUT, +PortH,PH9,,,,,I2C3_SMBA,,,,,TIM12_CH2,,,,DCMI_D0,,EVENTOUT, +PortH,PH10,,,TIM5_CH1,,,,,,,,,,,DCMI_D1,,EVENTOUT, +PortH,PH11,,,TIM5_CH2,,,,,,,,,,,DCMI_D2,,EVENTOUT, +PortH,PH12,,,TIM5_CH3,,,,,,,,,,,DCMI_D3,,EVENTOUT, +PortH,PH13,,,,TIM8_CH1N,,,,,,CAN1_TX,,,,,,EVENTOUT, +PortH,PH14,,,,TIM8_CH2N,,,,,,,,,,DCMI_D4,,EVENTOUT, +PortH,PH15,,,,TIM8_CH3N,,,,,,,,,,DCMI_D11,,EVENTOUT, +PortI,PI0,,,TIM5_CH4,,,SPI2_NSS/I2S2_WS,,,,,,,,DCMI_D13,,EVENTOUT, +PortI,PI1,,,,,,SPI2_SCK/I2S2_CK,,,,,,,,DCMI_D8,,EVENTOUT, +PortI,PI2,,,,TIM8_CH4,,SPI2_MISO,I2S2ext_SD,,,,,,,DCMI_D9,,EVENTOUT, +PortI,PI3,,,,TIM8_ETR,,SPI2_MOSI/I2S2_SD,,,,,,,,DCMI_D10,,EVENTOUT, +PortI,PI4,,,,TIM8_BKIN,,,,,,,,,,DCMI_D5,,EVENTOUT, +PortI,PI5,,,,TIM8_CH1,,,,,,,,,,DCMI_VSYNC,,EVENTOUT, +PortI,PI6,,,,TIM8_CH2,,,,,,,,,,DCMI_D6,,EVENTOUT, +PortI,PI7,,,,TIM8_CH3,,,,,,,,,,DCMI_D7,,EVENTOUT, +PortI,PI8,,,,,,,,,,,,,,,,EVENTOUT, +PortI,PI9,,,,,,,,,,CAN1_RX,,,,,,EVENTOUT, +PortI,PI10,,,,,,,,,,,,ETH_MII_RX_ER,,,,EVENTOUT, +PortI,PI11,,,,,,,,,,,OTG_HS_ULPI_DIR,,,,,EVENTOUT, From d3439d0c6065bc60a9c4c915f4a1a3ffa796cf33 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 2 Jun 2014 19:37:55 +0300 Subject: [PATCH 05/11] py: Instead of having "debug on" var, have "optimization level" var. This allows to have multiple "optimization" levels (CPython has two (-OO removes docstrings), we can have more). --- py/lexer.c | 9 ++------- py/lexer.h | 2 ++ py/runtime.c | 5 +++-- py/runtime.h | 2 -- unix/main.c | 12 +++++++++--- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/py/lexer.c b/py/lexer.c index 4a7ac071b4..26993922eb 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -64,12 +64,7 @@ struct _mp_lexer_t { mp_token_t tok_cur; }; -// debug flag for __debug__ constant -STATIC mp_token_kind_t mp_debug_value; - -void mp_set_debug(bool value) { - mp_debug_value = value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE; -} +uint mp_optimise_value; // TODO replace with a call to a standard function bool str_strn_equal(const char *str, const char *strn, int len) { @@ -703,7 +698,7 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs if (str_strn_equal(tok_kw[i], tok->str, tok->len)) { if (i == ARRAY_SIZE(tok_kw) - 1) { // tok_kw[ARRAY_SIZE(tok_kw) - 1] == "__debug__" - tok->kind = mp_debug_value; + tok->kind = (mp_optimise_value == 0 ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE); } else { tok->kind = MP_TOKEN_KW_FALSE + i; } diff --git a/py/lexer.h b/py/lexer.h index b302cb2db1..24cae1e252 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -176,3 +176,5 @@ typedef enum { mp_import_stat_t mp_import_stat(const char *path); mp_lexer_t *mp_lexer_new_from_file(const char *filename); + +extern uint mp_optimise_value; diff --git a/py/runtime.c b/py/runtime.c index ecaf40deb4..27a5ed5439 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -45,6 +45,7 @@ #include "bc.h" #include "smallint.h" #include "objgenerator.h" +#include "lexer.h" #if 0 // print debugging info #define DEBUG_PRINT (1) @@ -74,8 +75,8 @@ void mp_init(void) { MICROPY_PORT_INIT_FUNC; #endif - // __debug__ enabled by default - mp_set_debug(true); + // optimization disabled by default + mp_optimise_value = 0; // init global module stuff mp_module_init(); diff --git a/py/runtime.h b/py/runtime.h index 3c79b48ed0..dbd413180b 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -54,8 +54,6 @@ typedef struct _mp_arg_t { void mp_init(void); void mp_deinit(void); -void mp_set_debug(bool value); // sets the value of __debug__; see lexer.c - void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw); void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); diff --git a/unix/main.c b/unix/main.c index 992ea1fec5..7c3fbf6aa1 100644 --- a/unix/main.c +++ b/unix/main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -188,6 +189,7 @@ int usage(char **argv) { "usage: %s [] [-X ] [-c ] []\n" "Options:\n" "-v : verbose (trace various operations); can be multiple\n" +"-O[N] : apply bytecode optimizations of level N\n" "\n" "Implementation specific options:\n", argv[0] ); @@ -346,9 +348,13 @@ int main(int argc, char **argv) { a += 1; } else if (strcmp(argv[a], "-v") == 0) { mp_verbose_flag++; - } else if (strcmp(argv[a], "-O") == 0) { - // optimisation; sets __debug__ to False - mp_set_debug(false); + } else if (strncmp(argv[a], "-O", 2) == 0) { + if (isdigit(argv[a][2])) { + mp_optimise_value = argv[a][2] & 0xf; + } else { + mp_optimise_value = 0; + for (char *p = argv[a] + 1; *p && *p == 'O'; p++, mp_optimise_value++); + } } else { return usage(argv); } From b8f117dd32aae6d2d8108ba101961d00df123e4f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 2 Jun 2014 19:39:15 +0300 Subject: [PATCH 06/11] py: For optimization level -O3 and higher, remove lineno info from bytecode. --- py/emitbc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py/emitbc.c b/py/emitbc.c index cfaea7c88a..841dd4aabb 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -352,6 +352,10 @@ STATIC void emit_bc_adjust_stack_size(emit_t *emit, int delta) { STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) { //printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->bytecode_offset); #if MICROPY_ENABLE_SOURCE_LINE + if (mp_optimise_value >= 3) { + // If we compile with -O3, don't store line numbers. + return; + } if (source_line > emit->last_source_line) { uint bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset; uint lines_to_skip = source_line - emit->last_source_line; From 411732e93bcbeb529bc5f9722015b61c63eef3c5 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 2 Jun 2014 18:24:34 +0300 Subject: [PATCH 07/11] vm: If there's no lineno info, set lineno in traceback to 0, not 1. To clearly signify that lineno is not known. --- py/vm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/py/vm.c b/py/vm.c index cfb390bae7..d57fbf17e3 100644 --- a/py/vm.c +++ b/py/vm.c @@ -1042,12 +1042,16 @@ exception_handler: machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24); qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); - machine_uint_t source_line = 1; + machine_uint_t source_line = 0; machine_uint_t bc = code_state->ip - code_info - code_info_size; //printf("find %lu %d %d\n", bc, code_info[12], code_info[13]); - for (const byte* ci = code_info + 12; *ci && bc >= ((*ci) & 31); ci++) { - bc -= *ci & 31; - source_line += *ci >> 5; + const byte* ci = code_info + 12; + if (*ci) { + source_line = 1; + for (; *ci && bc >= ((*ci) & 31); ci++) { + bc -= *ci & 31; + source_line += *ci >> 5; + } } mp_obj_exception_add_traceback(nlr.ret_val, source_file, source_line, block_name); } From bcb6ca4d5e926d9571d150fb045c5ac4b53f8ecd Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 3 Jun 2014 12:53:44 +0100 Subject: [PATCH 08/11] py: Implement full behaviour of dict.update(), and dict(). Add keyword args to dict.update(), and ability to take a dictionary as argument. dict() class constructor can now use dict.update() directly. This patch loses fast path for dict(other_dict), but is that really needed? Any anyway, this idiom will now re-hash the dictionary, so is arguably more memory efficient. Addresses issue #647. --- py/objdict.c | 105 ++++++++++++++++----------------- tests/basics/dict_construct.py | 16 +++++ tests/basics/dict_update.py | 6 ++ 3 files changed, 74 insertions(+), 53 deletions(-) create mode 100644 tests/basics/dict_construct.py diff --git a/py/objdict.c b/py/objdict.c index f41eacd939..8a0a08772a 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -40,7 +40,7 @@ STATIC mp_obj_t mp_obj_new_dict_iterator(mp_obj_dict_t *dict, int cur); STATIC mp_map_elem_t *dict_it_iternext_elem(mp_obj_t self_in); -STATIC mp_obj_t dict_copy(mp_obj_t self_in); +STATIC mp_obj_t dict_update(uint n_args, const mp_obj_t *args, mp_map_t *kwargs); STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { mp_obj_dict_t *self = self_in; @@ -61,40 +61,13 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env } STATIC mp_obj_t dict_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - mp_obj_t dict; - switch (n_args) { - case 0: - dict = mp_obj_new_dict(0); - break; - - case 1: { - if (MP_OBJ_IS_TYPE(args[0], &mp_type_dict)) { - return dict_copy(args[0]); - } - // TODO create dict from an arbitrary mapping! - - // Make dict from iterable of pairs - mp_obj_t iterable = mp_getiter(args[0]); - mp_obj_t dict = mp_obj_new_dict(0); - // TODO: support arbitrary seq as a pair - mp_obj_t item; - while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - mp_obj_t *sub_items; - mp_obj_get_array_fixed_n(item, 2, &sub_items); - mp_obj_dict_store(dict, sub_items[0], sub_items[1]); - } - return dict; - } - - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "dict takes at most 1 argument")); + mp_obj_t dict = mp_obj_new_dict(0); + if (n_args > 0 || n_kw > 0) { + mp_obj_t args2[2] = {dict, args[0]}; // args[0] is always valid, even if it's not a positional arg + mp_map_t kwargs; + mp_map_init_fixed_table(&kwargs, n_kw, args + n_args); + dict_update(n_args + 1, args2, &kwargs); // dict_update will check that n_args + 1 == 1 or 2 } - - // add to the new dict any keyword args - for (const mp_obj_t *a = args + n_args; n_kw > 0; n_kw--, a += 2) { - mp_obj_dict_store(dict, a[0], a[1]); - } - return dict; } @@ -348,31 +321,57 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_popitem_obj, dict_popitem); -STATIC mp_obj_t dict_update(mp_obj_t self_in, mp_obj_t iterable) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_dict)); - mp_obj_dict_t *self = self_in; - /* TODO: check for the "keys" method */ - mp_obj_t iter = mp_getiter(iterable); - mp_obj_t next = NULL; - while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { - mp_obj_t inneriter = mp_getiter(next); - mp_obj_t key = mp_iternext(inneriter); - mp_obj_t value = mp_iternext(inneriter); - mp_obj_t stop = mp_iternext(inneriter); - if (key == MP_OBJ_STOP_ITERATION - || value == MP_OBJ_STOP_ITERATION - || stop != MP_OBJ_STOP_ITERATION) { - nlr_raise(mp_obj_new_exception_msg( - &mp_type_ValueError, - "dictionary update sequence has the wrong length")); +STATIC mp_obj_t dict_update(uint n_args, const mp_obj_t *args, mp_map_t *kwargs) { + assert(MP_OBJ_IS_TYPE(args[0], &mp_type_dict)); + mp_obj_dict_t *self = args[0]; + + mp_arg_check_num(n_args, kwargs->used, 1, 2, true); + + if (n_args == 2) { + // given a positional argument + + if (MP_OBJ_IS_TYPE(args[1], &mp_type_dict)) { + // update from other dictionary (make sure other is not self) + if (args[1] != self) { + // TODO don't allocate heap object for this iterator + mp_obj_t *dict_iter = mp_obj_new_dict_iterator(args[1], 0); + mp_map_elem_t *elem = NULL; + while ((elem = dict_it_iternext_elem(dict_iter)) != MP_OBJ_STOP_ITERATION) { + mp_map_lookup(&self->map, elem->key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = elem->value; + } + } } else { - mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; + // update from a generic iterable of pairs + mp_obj_t iter = mp_getiter(args[1]); + mp_obj_t next = NULL; + while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { + mp_obj_t inneriter = mp_getiter(next); + mp_obj_t key = mp_iternext(inneriter); + mp_obj_t value = mp_iternext(inneriter); + mp_obj_t stop = mp_iternext(inneriter); + if (key == MP_OBJ_STOP_ITERATION + || value == MP_OBJ_STOP_ITERATION + || stop != MP_OBJ_STOP_ITERATION) { + nlr_raise(mp_obj_new_exception_msg( + &mp_type_ValueError, + "dictionary update sequence has the wrong length")); + } else { + mp_map_lookup(&self->map, key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value; + } + } + } + } + + // update the dict with any keyword args + for (machine_uint_t i = 0; i < kwargs->alloc; i++) { + if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) { + mp_map_lookup(&self->map, kwargs->table[i].key, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = kwargs->table[i].value; } } return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(dict_update_obj, dict_update); +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(dict_update_obj, 1, dict_update); /******************************************************************************/ diff --git a/tests/basics/dict_construct.py b/tests/basics/dict_construct.py new file mode 100644 index 0000000000..0035e9c0f9 --- /dev/null +++ b/tests/basics/dict_construct.py @@ -0,0 +1,16 @@ +# dict constructor + +d = dict() +print(d) + +d = dict({1:2}) +print(d) + +d = dict(a=1) +print(d) + +d = dict({1:2}, a=3) +print(d[1], d['a']) + +d = dict([(1, 2)], a=3, b=4) +print(d[1], d['a'], d['b']) diff --git a/tests/basics/dict_update.py b/tests/basics/dict_update.py index 46d1f41b5f..ab1a63304a 100644 --- a/tests/basics/dict_update.py +++ b/tests/basics/dict_update.py @@ -8,3 +8,9 @@ print(len(d)) d.update([(1,4)]) print(d[1]) print(len(d)) + +# using keywords +d.update(a=5) +print(d['a']) +d.update([(1,5)], b=6) +print(d[1], d['b']) From 65ec33200ada958066bea0914120045acdb5e410 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 3 Jun 2014 12:33:38 +0000 Subject: [PATCH 09/11] py: Fix configuration of math module. --- py/builtintables.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/py/builtintables.c b/py/builtintables.c index 628514da1c..49b0ed93e4 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -171,12 +171,12 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_struct }, #endif -#if MICROPY_PY_BUILTINS_FLOAT +#if MICROPY_PY_MATH { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math }, +#endif #if MICROPY_PY_CMATH { MP_OBJ_NEW_QSTR(MP_QSTR_cmath), (mp_obj_t)&mp_module_cmath }, #endif -#endif #if MICROPY_PY_SYS { MP_OBJ_NEW_QSTR(MP_QSTR_sys), (mp_obj_t)&mp_module_sys }, #endif From 3f5226246517be2f28d4f23d6e4c202047915f83 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 3 Jun 2014 13:40:16 +0100 Subject: [PATCH 10/11] py: Allow tail call optimisation in mp_call_function_n_kw. This saves 4 words of stack space per Python call. --- py/objtype.c | 2 +- py/runtime.c | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/py/objtype.c b/py/objtype.c index ebbb6097dd..a51e12f1fd 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -516,7 +516,7 @@ STATIC mp_obj_t instance_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp mp_obj_t member[2] = {MP_OBJ_NULL}; mp_obj_class_lookup(self, self->base.type, MP_QSTR___call__, offsetof(mp_obj_type_t, call), member); if (member[0] == MP_OBJ_NULL) { - return MP_OBJ_NULL; + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(self_in))); } if (member[0] == MP_OBJ_SENTINEL) { return mp_call_function_n_kw(self->subobj[0], n_args, n_kw, args); diff --git a/py/runtime.c b/py/runtime.c index 27a5ed5439..f13cc1d892 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -526,10 +526,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, uint n_args, uint n_kw, const mp // do the call if (type->call != NULL) { - mp_obj_t res = type->call(fun_in, n_args, n_kw, args); - if (res != NULL) { - return res; - } + return type->call(fun_in, n_args, n_kw, args); } nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(fun_in))); From b294a7e3c9b84aad6c331128a51e0d69e7845141 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 3 Jun 2014 13:43:20 +0100 Subject: [PATCH 11/11] py: Properly fix configuration of float and math module. --- py/builtintables.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/py/builtintables.c b/py/builtintables.c index 49b0ed93e4..1041c2598c 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -171,12 +171,14 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_struct }, #endif +#if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_PY_MATH { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math }, #endif #if MICROPY_PY_CMATH { MP_OBJ_NEW_QSTR(MP_QSTR_cmath), (mp_obj_t)&mp_module_cmath }, #endif +#endif #if MICROPY_PY_SYS { MP_OBJ_NEW_QSTR(MP_QSTR_sys), (mp_obj_t)&mp_module_sys }, #endif