From 7dc2345715f6c0619e833661d709f6e4e550d7b5 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 7 Oct 2016 15:59:50 +1100 Subject: py/modmicropython: Add micropython.opt_level([value]) function. This allows to get/set at runtime the optimisation level of the compiler. --- py/modmicropython.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'py') diff --git a/py/modmicropython.c b/py/modmicropython.c index f7d74db2e..675d169cc 100644 --- a/py/modmicropython.c +++ b/py/modmicropython.c @@ -34,6 +34,16 @@ // Various builtins specific to MicroPython runtime, // living in micropython module +STATIC mp_obj_t mp_micropython_opt_level(size_t n_args, const mp_obj_t *args) { + if (n_args == 0) { + return MP_OBJ_NEW_SMALL_INT(MP_STATE_VM(mp_optimise_value)); + } else { + MP_STATE_VM(mp_optimise_value) = mp_obj_get_int(args[0]); + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_micropython_opt_level_obj, 0, 1, mp_micropython_opt_level); + #if MICROPY_PY_MICROPYTHON_MEM_INFO #if MICROPY_MEM_STATS @@ -121,6 +131,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_alloc_emergency_exception_buf_obj, mp_alloc_ STATIC const mp_rom_map_elem_t mp_module_micropython_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_micropython) }, { MP_ROM_QSTR(MP_QSTR_const), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR_opt_level), MP_ROM_PTR(&mp_micropython_opt_level_obj) }, #if MICROPY_PY_MICROPYTHON_MEM_INFO #if MICROPY_MEM_STATS { MP_ROM_QSTR(MP_QSTR_mem_total), MP_ROM_PTR(&mp_micropython_mem_total_obj) }, -- cgit v1.2.3 From e49153fb98ade48395b80271093bd763e771b3da Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2016 12:29:54 +1100 Subject: py/compile: Remove unreachable code. --- py/compile.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'py') diff --git a/py/compile.c b/py/compile.c index 0ea8a3c15..de75bcdc3 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2836,12 +2836,10 @@ STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn) // no annotation return; } - } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star) { + } else { + assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star); // double star with possible annotation // fallthrough - } else { - // no annotation - return; } mp_parse_node_t pn_annotation = pns->nodes[1]; -- cgit v1.2.3 From 48874942f0e0c948a9cb351b25d9fb04cdb82d56 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2016 13:00:01 +1100 Subject: py/mpz: In divmod, replace check for rhs!=0 with assert. The check for division by zero is made by the caller of this function. --- py/mpz.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'py') diff --git a/py/mpz.c b/py/mpz.c index bb7647956..b5ec171de 100644 --- a/py/mpz.c +++ b/py/mpz.c @@ -1497,13 +1497,10 @@ mpz_t *mpz_lcm(const mpz_t *z1, const mpz_t *z2) { quo * rhs + rem = lhs 0 <= rem < rhs can have lhs, rhs the same + assumes rhs != 0 (undefined behaviour if it is) */ void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs) { - if (rhs->len == 0) { - mpz_set_from_int(dest_quo, 0); - mpz_set_from_int(dest_rem, 0); - return; - } + assert(!mpz_is_zero(rhs)); mpz_need_dig(dest_quo, lhs->len + 1); // +1 necessary? memset(dest_quo->dig, 0, (lhs->len + 1) * sizeof(mpz_dig_t)); -- cgit v1.2.3 From df3e5d2b2f8610d246fea348bb96e70f636183ea Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2016 13:00:56 +1100 Subject: py/mpz: Use assert to verify mpz does not have a fixed digit buffer. --- py/mpz.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'py') diff --git a/py/mpz.c b/py/mpz.c index b5ec171de..6415e1df4 100644 --- a/py/mpz.c +++ b/py/mpz.c @@ -734,11 +734,9 @@ STATIC void mpz_need_dig(mpz_t *z, mp_uint_t need) { } if (z->dig == NULL || z->alloc < need) { - if (z->fixed_dig) { - // cannot reallocate fixed buffers - assert(0); - return; - } + // if z has fixed digit buffer there's not much we can do as the caller will + // be expecting a buffer with at least "need" bytes (but it shouldn't happen) + assert(!z->fixed_dig); z->dig = m_renew(mpz_dig_t, z->dig, z->alloc, need); z->alloc = need; } -- cgit v1.2.3 From 8bb7d958f173eec58892bc00115516c160f93243 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2016 13:11:32 +1100 Subject: py: Factor duplicated function to calculate size of formatted int. --- py/mpz.c | 26 +------------------------- py/mpz.h | 1 + py/objint.c | 10 +++++----- py/objint.h | 2 ++ py/objint_mpz.c | 2 +- 5 files changed, 10 insertions(+), 31 deletions(-) (limited to 'py') diff --git a/py/mpz.c b/py/mpz.c index 6415e1df4..cceb079cd 100644 --- a/py/mpz.c +++ b/py/mpz.c @@ -645,18 +645,6 @@ STATIC void mpn_div(mpz_dig_t *num_dig, mp_uint_t *num_len, const mpz_dig_t *den #define MIN_ALLOC (2) -STATIC const uint8_t log_base2_floor[] = { - 0, - 0, 1, 1, 2, - 2, 2, 2, 3, - 3, 3, 3, 3, - 3, 3, 3, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 5 -}; - void mpz_init_zero(mpz_t *z) { z->neg = 0; z->fixed_dig = 0; @@ -1652,18 +1640,6 @@ mp_float_t mpz_as_float(const mpz_t *i) { } #endif -mp_uint_t mpz_as_str_size(const mpz_t *i, mp_uint_t base, const char *prefix, char comma) { - if (base < 2 || base > 32) { - return 0; - } - - mp_uint_t num_digits = i->len * DIG_SIZE / log_base2_floor[base] + 1; - mp_uint_t num_commas = comma ? num_digits / 3: 0; - mp_uint_t prefix_len = prefix ? strlen(prefix) : 0; - - return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte -} - #if 0 this function is unused char *mpz_as_str(const mpz_t *i, mp_uint_t base) { @@ -1673,7 +1649,7 @@ char *mpz_as_str(const mpz_t *i, mp_uint_t base) { } #endif -// assumes enough space as calculated by mpz_as_str_size +// assumes enough space as calculated by mp_int_format_size // returns length of string, not including null byte mp_uint_t mpz_as_str_inpl(const mpz_t *i, mp_uint_t base, const char *prefix, char base_char, char comma, char *str) { if (str == NULL || base < 2 || base > 32) { diff --git a/py/mpz.h b/py/mpz.h index 63ac772ff..55ef3e15f 100644 --- a/py/mpz.h +++ b/py/mpz.h @@ -127,6 +127,7 @@ void mpz_or_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs); void mpz_xor_inpl(mpz_t *dest, const mpz_t *lhs, const mpz_t *rhs); void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const mpz_t *rhs); +static inline size_t mpz_max_num_bits(const mpz_t *z) { return z->len * MPZ_DIG_SIZE; } mp_int_t mpz_hash(const mpz_t *z); bool mpz_as_int_checked(const mpz_t *z, mp_int_t *value); bool mpz_as_uint_checked(const mpz_t *z, mp_uint_t *value); diff --git a/py/objint.c b/py/objint.c index 9f948a145..31067aaa5 100644 --- a/py/objint.c +++ b/py/objint.c @@ -162,14 +162,14 @@ STATIC const uint8_t log_base2_floor[] = { 4, 4, 4, 5 }; -STATIC uint int_as_str_size_formatted(uint base, const char *prefix, char comma) { +size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma) { if (base < 2 || base > 32) { return 0; } - uint num_digits = sizeof(fmt_int_t) * 8 / log_base2_floor[base] + 1; - uint num_commas = comma ? num_digits / 3: 0; - uint prefix_len = prefix ? strlen(prefix) : 0; + size_t num_digits = num_bits / log_base2_floor[base] + 1; + size_t num_commas = comma ? num_digits / 3 : 0; + size_t prefix_len = prefix ? strlen(prefix) : 0; return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte } @@ -211,7 +211,7 @@ char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, sign = '-'; } - uint needed_size = int_as_str_size_formatted(base, prefix, comma); + uint needed_size = mp_int_format_size(sizeof(fmt_int_t) * 8, base, prefix, comma); if (needed_size > *buf_size) { *buf = m_new(char, needed_size); *buf_size = needed_size; diff --git a/py/objint.h b/py/objint.h index c79eb874a..dc53e0708 100644 --- a/py/objint.h +++ b/py/objint.h @@ -50,6 +50,8 @@ typedef enum { mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val); #endif // MICROPY_PY_BUILTINS_FLOAT +size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma); + void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in, int base, const char *prefix, char base_char, char comma); diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 3a30eb9d9..137d514de 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -95,7 +95,7 @@ char *mp_obj_int_formatted_impl(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_ assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t needed_size = mpz_as_str_size(&self->mpz, base, prefix, comma); + mp_uint_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma); if (needed_size > *buf_size) { *buf = m_new(char, needed_size); *buf_size = needed_size; -- cgit v1.2.3 From 6dff3df501242d106590a48b5ed382b01a97baea Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2016 13:20:11 +1100 Subject: py/objint: Use size_t for arguments that measure bytes/sizes. --- py/mpprint.c | 4 ++-- py/objint.c | 8 ++++---- py/objint.h | 6 +++--- py/objint_longlong.c | 2 +- py/objint_mpz.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) (limited to 'py') diff --git a/py/mpprint.c b/py/mpprint.c index 97ea33ad2..9ad0f3f9a 100644 --- a/py/mpprint.c +++ b/py/mpprint.c @@ -252,8 +252,8 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char // enough, a dynamic one will be allocated. char stack_buf[sizeof(mp_int_t) * 4]; char *buf = stack_buf; - mp_uint_t buf_size = sizeof(stack_buf); - mp_uint_t fmt_size = 0; + size_t buf_size = sizeof(stack_buf); + size_t fmt_size = 0; char *str; if (prec > 1) { diff --git a/py/objint.c b/py/objint.c index 31067aaa5..49dec0653 100644 --- a/py/objint.c +++ b/py/objint.c @@ -133,8 +133,8 @@ void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t // enough, a dynamic one will be allocated. char stack_buf[sizeof(mp_int_t) * 4]; char *buf = stack_buf; - mp_uint_t buf_size = sizeof(stack_buf); - mp_uint_t fmt_size; + size_t buf_size = sizeof(stack_buf); + size_t fmt_size; char *str = mp_obj_int_formatted(&buf, &buf_size, &fmt_size, self_in, 10, NULL, '\0', '\0'); mp_print_str(print, str); @@ -180,7 +180,7 @@ size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char co // // The resulting formatted string will be returned from this function and the // formatted size will be in *fmt_size. -char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in, +char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in, int base, const char *prefix, char base_char, char comma) { fmt_int_t num; if (MP_OBJ_IS_SMALL_INT(self_in)) { @@ -211,7 +211,7 @@ char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, sign = '-'; } - uint needed_size = mp_int_format_size(sizeof(fmt_int_t) * 8, base, prefix, comma); + size_t needed_size = mp_int_format_size(sizeof(fmt_int_t) * 8, base, prefix, comma); if (needed_size > *buf_size) { *buf = m_new(char, needed_size); *buf_size = needed_size; diff --git a/py/objint.h b/py/objint.h index dc53e0708..6e627f1bd 100644 --- a/py/objint.h +++ b/py/objint.h @@ -53,12 +53,12 @@ mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val); size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma); void mp_obj_int_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind); -char *mp_obj_int_formatted(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in, +char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in, int base, const char *prefix, char base_char, char comma); -char *mp_obj_int_formatted_impl(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in, +char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in, int base, const char *prefix, char base_char, char comma); mp_int_t mp_obj_int_hash(mp_obj_t self_in); -void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, mp_uint_t len, byte *buf); +void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf); int mp_obj_int_sign(mp_obj_t self_in); mp_obj_t mp_obj_int_abs(mp_obj_t self_in); mp_obj_t mp_obj_int_unary_op(mp_uint_t op, mp_obj_t o_in); diff --git a/py/objint_longlong.c b/py/objint_longlong.c index f10e46447..b051cfbe6 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -53,7 +53,7 @@ const mp_obj_int_t mp_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX}; #endif -void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, mp_uint_t len, byte *buf) { +void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); mp_obj_int_t *self = self_in; long long val = self->val; diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 137d514de..6a59133d7 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -90,12 +90,12 @@ STATIC mp_obj_int_t *mp_obj_int_new_mpz(void) { // formatted size will be in *fmt_size. // // This particular routine should only be called for the mpz representation of the int. -char *mp_obj_int_formatted_impl(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_size, mp_const_obj_t self_in, +char *mp_obj_int_formatted_impl(char **buf, size_t *buf_size, size_t *fmt_size, mp_const_obj_t self_in, int base, const char *prefix, char base_char, char comma) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); - mp_uint_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma); + size_t needed_size = mp_int_format_size(mpz_max_num_bits(&self->mpz), base, prefix, comma); if (needed_size > *buf_size) { *buf = m_new(char, needed_size); *buf_size = needed_size; @@ -107,7 +107,7 @@ char *mp_obj_int_formatted_impl(char **buf, mp_uint_t *buf_size, mp_uint_t *fmt_ return str; } -void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, mp_uint_t len, byte *buf) { +void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_int)); mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); mpz_as_bytes(&self->mpz, big_endian, len, buf); -- cgit v1.2.3 From deaa57acf3db104e2c1a54c6bf4bbd96f95583f4 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 12 Oct 2016 10:20:48 +1100 Subject: py/compile: Remove debugging code for compiler dispatch. It was a relic from the days of developing the compiler and is no longer needed, and it's impossible to trigger via a test. --- py/compile.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'py') diff --git a/py/compile.c b/py/compile.c index de75bcdc3..f84d5e214 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2723,15 +2723,8 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) { mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; EMIT_ARG(set_source_line, pns->source_line); compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)]; - if (f == NULL) { -#if MICROPY_DEBUG_PRINTERS - printf("node %u cannot be compiled\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns)); - mp_parse_node_print(pn, 0); -#endif - compile_syntax_error(comp, pn, "internal compiler error"); - } else { - f(comp, pns); - } + assert(f != NULL); + f(comp, pns); } } -- cgit v1.2.3 From 31101d91ceb5758c17d02b7d41bffbd387cad112 Mon Sep 17 00:00:00 2001 From: Damien George Date: Wed, 12 Oct 2016 11:00:17 +1100 Subject: py/lexer: Remove unnecessary code, and unreachable code. Setting emit_dent=0 is unnecessary because arriving in that part of the if-logic will guarantee that emit_dent is already zero. The block to check indent_top(lex)>0 is unreachable because a newline is always inserted an the end of the input stream, and hence dedents are always processed before EOF. --- py/lexer.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'py') diff --git a/py/lexer.c b/py/lexer.c index b2c9c5ff7..4a7c8f580 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -343,7 +343,6 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, bool first_token) { lex->tok_kind = MP_TOKEN_NEWLINE; mp_uint_t num_spaces = lex->column - 1; - lex->emit_dent = 0; if (num_spaces == indent_top(lex)) { } else if (num_spaces > indent_top(lex)) { indent_push(lex, num_spaces); @@ -359,16 +358,7 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, bool first_token) { } } else if (is_end(lex)) { - if (indent_top(lex) > 0) { - lex->tok_kind = MP_TOKEN_NEWLINE; - lex->emit_dent = 0; - while (indent_top(lex) > 0) { - indent_pop(lex); - lex->emit_dent -= 1; - } - } else { - lex->tok_kind = MP_TOKEN_END; - } + lex->tok_kind = MP_TOKEN_END; } else if (is_char_or(lex, '\'', '\"') || (is_char_or3(lex, 'r', 'u', 'b') && is_char_following_or(lex, '\'', '\"')) -- cgit v1.2.3 From af8d791bd09e2d735ec59424ec05f495348d99e7 Mon Sep 17 00:00:00 2001 From: Damien George Date: Tue, 11 Oct 2016 16:23:20 +1100 Subject: esp8266: Enable importing of precompiled .mpy files. --- esp8266/mpconfigport.h | 1 + py/emitglue.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'py') diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index ee32a848d..33f319f69 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -9,6 +9,7 @@ #define MICROPY_ALLOC_PARSE_RULE_INC (8) #define MICROPY_ALLOC_PARSE_RESULT_INC (8) #define MICROPY_ALLOC_PARSE_CHUNK_INIT (64) +#define MICROPY_PERSISTENT_CODE_LOAD (1) #define MICROPY_EMIT_X64 (0) #define MICROPY_EMIT_THUMB (0) #define MICROPY_EMIT_INLINE_THUMB (0) diff --git a/py/emitglue.c b/py/emitglue.c index f4b59df3e..dc5be6e0e 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -425,7 +425,7 @@ mp_raw_code_t *mp_raw_code_load_file(const char *filename) { return rc; } -#elif defined(__thumb2__) +#elif defined(__thumb2__) || defined(__xtensa__) // fatfs file reader (assume thumb2 arch uses fatfs...) #include "lib/fatfs/ff.h" -- cgit v1.2.3 From e93c1ca5da58df336305c9a5e50214849342f298 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 13 Oct 2016 11:43:28 +1100 Subject: extmod/modujson: Implement ujson.load() to load JSON from a stream. This refactors ujson.loads(s) to behave as ujson.load(StringIO(s)). Increase in code size is: 366 bytes for unix x86-64, 180 bytes for stmhal, 84 bytes for esp8266. --- extmod/modujson.c | 107 +++++++++++++++++++++++++++++++++++------------------- py/objstringio.c | 8 +--- py/objstringio.h | 38 +++++++++++++++++++ 3 files changed, 109 insertions(+), 44 deletions(-) create mode 100644 py/objstringio.h (limited to 'py') diff --git a/extmod/modujson.c b/extmod/modujson.c index 0d0781e06..193292b9e 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -1,9 +1,9 @@ /* - * This file is part of the Micro Python project, http://micropython.org/ + * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * - * Copyright (c) 2014 Damien P. George + * Copyright (c) 2014-2016 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -28,8 +28,10 @@ #include "py/nlr.h" #include "py/objlist.h" +#include "py/objstringio.h" #include "py/parsenum.h" #include "py/runtime.h" +#include "py/stream.h" #if MICROPY_PY_UJSON @@ -42,7 +44,7 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); -// This function implements a simple non-recursive JSON parser. +// The function below implements a simple non-recursive JSON parser. // // The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt // The parser here will parse any valid JSON and return the correct @@ -52,13 +54,35 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); // input is outside it's specs. // // Most of the work is parsing the primitives (null, false, true, numbers, -// strings). It does 1 pass over the input string and so is easily extended to -// being able to parse from a non-seekable stream. It tries to be fast and +// strings). It does 1 pass over the input stream. It tries to be fast and // small in code size, while not using more RAM than necessary. -STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { - mp_uint_t len; - const char *s = mp_obj_str_get_data(obj, &len); - const char *top = s + len; + +typedef struct _ujson_stream_t { + mp_obj_t stream_obj; + mp_uint_t (*read)(mp_obj_t obj, void *buf, mp_uint_t size, int *errcode); + int errcode; + byte cur; +} ujson_stream_t; + +#define S_EOF (0) // null is not allowed in json stream so is ok as EOF marker +#define S_END(s) ((s).cur == S_EOF) +#define S_CUR(s) ((s).cur) +#define S_NEXT(s) (ujson_stream_next(&(s))) + +STATIC byte ujson_stream_next(ujson_stream_t *s) { + mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode); + if (s->errcode != 0) { + mp_raise_OSError(s->errcode); + } + if (ret == 0) { + s->cur = S_EOF; + } + return s->cur; +} + +STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) { + const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ); + ujson_stream_t s = {stream_obj, stream_p->read, 0, 0}; vstr_t vstr; vstr_init(&vstr, 8); mp_obj_list_t stack; // we use a list as a simple stack for nested JSON @@ -67,41 +91,43 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { mp_obj_t stack_top = MP_OBJ_NULL; mp_obj_type_t *stack_top_type = NULL; mp_obj_t stack_key = MP_OBJ_NULL; + S_NEXT(s); for (;;) { cont: - if (s == top) { + if (S_END(s)) { break; } mp_obj_t next = MP_OBJ_NULL; bool enter = false; - switch (*s) { + byte cur = S_CUR(s); + S_NEXT(s); + switch (cur) { case ',': case ':': case ' ': case '\t': case '\n': case '\r': - s += 1; goto cont; case 'n': - if (s + 3 < top && s[1] == 'u' && s[2] == 'l' && s[3] == 'l') { - s += 4; + if (S_CUR(s) == 'u' && S_NEXT(s) == 'l' && S_NEXT(s) == 'l') { + S_NEXT(s); next = mp_const_none; } else { goto fail; } break; case 'f': - if (s + 4 < top && s[1] == 'a' && s[2] == 'l' && s[3] == 's' && s[4] == 'e') { - s += 5; + if (S_CUR(s) == 'a' && S_NEXT(s) == 'l' && S_NEXT(s) == 's' && S_NEXT(s) == 'e') { + S_NEXT(s); next = mp_const_false; } else { goto fail; } break; case 't': - if (s + 3 < top && s[1] == 'r' && s[2] == 'u' && s[3] == 'e') { - s += 4; + if (S_CUR(s) == 'r' && S_NEXT(s) == 'u' && S_NEXT(s) == 'e') { + S_NEXT(s); next = mp_const_true; } else { goto fail; @@ -109,11 +135,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { break; case '"': vstr_reset(&vstr); - for (s++; s < top && *s != '"';) { - byte c = *s; + for (; !S_END(s) && S_CUR(s) != '"';) { + byte c = S_CUR(s); if (c == '\\') { - s++; - c = *s; + c = S_NEXT(s); switch (c) { case 'b': c = 0x08; break; case 'f': c = 0x0c; break; @@ -121,10 +146,9 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { case 'r': c = 0x0d; break; case 't': c = 0x09; break; case 'u': { - if (s + 4 >= top) { goto fail; } mp_uint_t num = 0; for (int i = 0; i < 4; i++) { - c = (*++s | 0x20) - '0'; + c = (S_NEXT(s) | 0x20) - '0'; if (c > 9) { c -= ('a' - ('9' + 1)); } @@ -137,27 +161,29 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { } vstr_add_byte(&vstr, c); str_cont: - s++; + S_NEXT(s); } - if (s == top) { + if (S_END(s)) { goto fail; } - s++; + S_NEXT(s); next = mp_obj_new_str(vstr.buf, vstr.len, false); break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { bool flt = false; vstr_reset(&vstr); - for (; s < top; s++) { - if (*s == '.' || *s == 'E' || *s == 'e') { + for (;;) { + vstr_add_byte(&vstr, cur); + cur = S_CUR(s); + if (cur == '.' || cur == 'E' || cur == 'e') { flt = true; - } else if (*s == '-' || unichar_isdigit(*s)) { + } else if (cur == '-' || unichar_isdigit(cur)) { // pass } else { break; } - vstr_add_byte(&vstr, *s); + S_NEXT(s); } if (flt) { next = mp_parse_num_decimal(vstr.buf, vstr.len, false, false, NULL); @@ -169,16 +195,13 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { case '[': next = mp_obj_new_list(0, NULL); enter = true; - s += 1; break; case '{': next = mp_obj_new_dict(0); enter = true; - s += 1; break; case '}': case ']': { - s += 1; if (stack_top == MP_OBJ_NULL) { // no object at all goto fail; @@ -231,10 +254,10 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { } success: // eat trailing whitespace - while (s < top && unichar_isspace(*s)) { - s++; + while (unichar_isspace(S_CUR(s))) { + S_NEXT(s); } - if (s < top) { + if (!S_END(s)) { // unexpected chars goto fail; } @@ -248,11 +271,21 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { fail: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "syntax error in JSON")); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load); + +STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) { + mp_uint_t len; + const char *buf = mp_obj_str_get_data(obj, &len); + vstr_t vstr = {len, len, (char*)buf, true}; + mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0}; + return mod_ujson_load(&sio); +} STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads); STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) }, { MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) }, + { MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) }, { MP_ROM_QSTR(MP_QSTR_loads), MP_ROM_PTR(&mod_ujson_loads_obj) }, }; diff --git a/py/objstringio.c b/py/objstringio.c index eb0cc4eb3..be1a7d89c 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -30,18 +30,12 @@ #include "py/nlr.h" #include "py/objstr.h" +#include "py/objstringio.h" #include "py/runtime.h" #include "py/stream.h" #if MICROPY_PY_IO -typedef struct _mp_obj_stringio_t { - mp_obj_base_t base; - vstr_t *vstr; - // StringIO has single pointer used for both reading and writing - mp_uint_t pos; -} mp_obj_stringio_t; - #if MICROPY_CPYTHON_COMPAT STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) { if (o->vstr == NULL) { diff --git a/py/objstringio.h b/py/objstringio.h new file mode 100644 index 000000000..853bfb11b --- /dev/null +++ b/py/objstringio.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#ifndef MICROPY_INCLUDED_PY_OBJSTRINGIO_H +#define MICROPY_INCLUDED_PY_OBJSTRINGIO_H + +#include "py/obj.h" + +typedef struct _mp_obj_stringio_t { + mp_obj_base_t base; + vstr_t *vstr; + // StringIO has single pointer used for both reading and writing + mp_uint_t pos; +} mp_obj_stringio_t; + +#endif // MICROPY_INCLUDED_PY_OBJSTRINGIO_H -- cgit v1.2.3 From 824f5c5a32d740acad50d23b7ab1d69660dcf3ad Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 14 Oct 2016 16:46:34 +1100 Subject: py/vstr: Combine vstr_new_size with vstr_new since they are rarely used. Now there is just one function to allocate a new vstr, namely vstr_new (in addition to vstr_init etc). The caller of this function should know what initial size to allocate for the buffer, or at least have some policy or config option, instead of leaving it to a default (as it was before). --- lib/utils/pyexec.c | 2 +- py/misc.h | 3 +-- py/objstringio.c | 2 +- py/vstr.c | 14 +------------- teensy/main.c | 2 +- unix/coverage.c | 2 +- 6 files changed, 6 insertions(+), 19 deletions(-) (limited to 'py') diff --git a/lib/utils/pyexec.c b/lib/utils/pyexec.c index aac211894..5824e1403 100644 --- a/lib/utils/pyexec.c +++ b/lib/utils/pyexec.c @@ -148,7 +148,7 @@ STATIC int pyexec_raw_repl_process_char(int c); STATIC int pyexec_friendly_repl_process_char(int c); void pyexec_event_repl_init(void) { - MP_STATE_VM(repl_line) = vstr_new_size(32); + MP_STATE_VM(repl_line) = vstr_new(32); repl.cont_line = false; readline_init(MP_STATE_VM(repl_line), ">>> "); if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { diff --git a/py/misc.h b/py/misc.h index 3ed227a35..e60665e59 100644 --- a/py/misc.h +++ b/py/misc.h @@ -151,8 +151,7 @@ void vstr_init_fixed_buf(vstr_t *vstr, size_t alloc, char *buf); struct _mp_print_t; void vstr_init_print(vstr_t *vstr, size_t alloc, struct _mp_print_t *print); void vstr_clear(vstr_t *vstr); -vstr_t *vstr_new(void); -vstr_t *vstr_new_size(size_t alloc); +vstr_t *vstr_new(size_t alloc); void vstr_free(vstr_t *vstr); static inline void vstr_reset(vstr_t *vstr) { vstr->len = 0; } static inline char *vstr_str(vstr_t *vstr) { return vstr->buf; } diff --git a/py/objstringio.c b/py/objstringio.c index be1a7d89c..212d8e314 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -150,7 +150,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stringio___exit___obj, 4, 4, stringio STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) { mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t); o->base.type = type; - o->vstr = vstr_new(); + o->vstr = vstr_new(16); o->pos = 0; return o; } diff --git a/py/vstr.c b/py/vstr.c index 5096475f1..6a91552b5 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -74,20 +74,8 @@ void vstr_clear(vstr_t *vstr) { vstr->buf = NULL; } -vstr_t *vstr_new(void) { +vstr_t *vstr_new(size_t alloc) { vstr_t *vstr = m_new_obj(vstr_t); - if (vstr == NULL) { - return NULL; - } - vstr_init(vstr, 16); - return vstr; -} - -vstr_t *vstr_new_size(size_t alloc) { - vstr_t *vstr = m_new_obj(vstr_t); - if (vstr == NULL) { - return NULL; - } vstr_init(vstr, alloc); return vstr; } diff --git a/teensy/main.c b/teensy/main.c index 890ee8149..ba7207fe8 100644 --- a/teensy/main.c +++ b/teensy/main.c @@ -317,7 +317,7 @@ soft_reset: pyexec_frozen_module("main.py"); #else { - vstr_t *vstr = vstr_new(); + vstr_t *vstr = vstr_new(16); vstr_add_str(vstr, "/"); if (pyb_config_main == MP_OBJ_NULL) { vstr_add_str(vstr, "main.py"); diff --git a/unix/coverage.c b/unix/coverage.c index c84a653f7..6a1b43fdc 100644 --- a/unix/coverage.c +++ b/unix/coverage.c @@ -34,7 +34,7 @@ STATIC mp_obj_t extra_coverage(void) { // vstr { mp_printf(&mp_plat_print, "# vstr\n"); - vstr_t *vstr = vstr_new_size(16); + vstr_t *vstr = vstr_new(16); vstr_hint_size(vstr, 32); vstr_add_str(vstr, "ts"); vstr_ins_byte(vstr, 1, 'e'); -- cgit v1.2.3 From a97284423eba9470c16c5f02fadea14bd8263751 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 14 Oct 2016 20:13:02 +0300 Subject: extmod/utime_mphal: Factor out implementations in terms of mp_hal_* for reuse. As long as a port implement mp_hal_sleep_ms(), mp_hal_ticks_ms(), etc. functions, it can just use standard implementations of utime.sleel_ms(), utime.ticks_ms(), etc. Python-level functions. --- esp8266/modutime.c | 62 +++++-------------------------------- esp8266/mpconfigport.h | 1 + extmod/utime_mphal.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ extmod/utime_mphal.h | 36 ++++++++++++++++++++++ py/mpconfig.h | 6 ++++ py/mphal.h | 4 +++ py/py.mk | 1 + 7 files changed, 139 insertions(+), 54 deletions(-) create mode 100644 extmod/utime_mphal.c create mode 100644 extmod/utime_mphal.h (limited to 'py') diff --git a/esp8266/modutime.c b/esp8266/modutime.c index 4b94ace74..abfe069cc 100644 --- a/esp8266/modutime.c +++ b/esp8266/modutime.c @@ -38,6 +38,7 @@ #include "modpybrtc.h" #include "timeutils.h" #include "user_interface.h" +#include "extmod/utime_mphal.h" /// \module time - time related functions /// @@ -99,53 +100,6 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) { } MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime); -/// \function sleep(seconds) -/// Sleep for the given number of seconds. -STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { - #if MICROPY_PY_BUILTINS_FLOAT - mp_hal_delay_ms(1000 * mp_obj_get_float(seconds_o)); - #else - mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o)); - #endif - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_obj, time_sleep); - -STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) { - mp_hal_delay_ms(mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_ms_obj, time_sleep_ms); - -STATIC mp_obj_t time_sleep_us(mp_obj_t arg) { - mp_hal_delay_us(mp_obj_get_int(arg)); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(time_sleep_us_obj, time_sleep_us); - -STATIC mp_obj_t time_ticks_ms(void) { - return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_ms_obj, time_ticks_ms); - -STATIC mp_obj_t time_ticks_us(void) { - return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_us_obj, time_ticks_us); - -STATIC mp_obj_t time_ticks_cpu(void) { - return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_0(time_ticks_cpu_obj, time_ticks_cpu); - -STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) { - // we assume that the arguments come from ticks_xx so are small ints - uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in); - uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in); - return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(time_ticks_diff_obj, time_ticks_diff); - /// \function time() /// Returns the number of seconds, as an integer, since 1/1/2000. STATIC mp_obj_t time_time(void) { @@ -159,13 +113,13 @@ STATIC const mp_map_elem_t time_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_localtime), (mp_obj_t)&time_localtime_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mktime), (mp_obj_t)&time_mktime_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&time_sleep_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&time_sleep_ms_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&time_sleep_us_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&time_ticks_ms_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&time_ticks_us_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&time_ticks_cpu_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&time_ticks_diff_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&mp_utime_sleep_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_ms), (mp_obj_t)&mp_utime_sleep_ms_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep_us), (mp_obj_t)&mp_utime_sleep_us_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_ms), (mp_obj_t)&mp_utime_ticks_ms_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_us), (mp_obj_t)&mp_utime_ticks_us_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_cpu), (mp_obj_t)&mp_utime_ticks_cpu_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks_diff), (mp_obj_t)&mp_utime_ticks_diff_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_time_obj }, }; diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index 6d0deba8d..201057f12 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -62,6 +62,7 @@ #define MICROPY_PY_UJSON (1) #define MICROPY_PY_URANDOM (1) #define MICROPY_PY_URE (1) +#define MICROPY_PY_UTIME_MP_HAL (1) #define MICROPY_PY_UZLIB (1) #define MICROPY_PY_LWIP (1) #define MICROPY_PY_MACHINE (1) diff --git a/extmod/utime_mphal.c b/extmod/utime_mphal.c new file mode 100644 index 000000000..9471ad525 --- /dev/null +++ b/extmod/utime_mphal.c @@ -0,0 +1,83 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mpconfig.h" +#if MICROPY_PY_UTIME_MP_HAL + +#include + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/smallint.h" +#include "extmod/utime_mphal.h" + +STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) { + #if MICROPY_PY_BUILTINS_FLOAT + mp_hal_delay_ms(1000 * mp_obj_get_float(seconds_o)); + #else + mp_hal_delay_ms(1000 * mp_obj_get_int(seconds_o)); + #endif + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_obj, time_sleep); + +STATIC mp_obj_t time_sleep_ms(mp_obj_t arg) { + mp_hal_delay_ms(mp_obj_get_int(arg)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_ms_obj, time_sleep_ms); + +STATIC mp_obj_t time_sleep_us(mp_obj_t arg) { + mp_hal_delay_us(mp_obj_get_int(arg)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mp_utime_sleep_us_obj, time_sleep_us); + +STATIC mp_obj_t time_ticks_ms(void) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_ms_obj, time_ticks_ms); + +STATIC mp_obj_t time_ticks_us(void) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_us() & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_us_obj, time_ticks_us); + +STATIC mp_obj_t time_ticks_cpu(void) { + return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_cpu() & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_0(mp_utime_ticks_cpu_obj, time_ticks_cpu); + +STATIC mp_obj_t time_ticks_diff(mp_obj_t start_in, mp_obj_t end_in) { + // we assume that the arguments come from ticks_xx so are small ints + uint32_t start = MP_OBJ_SMALL_INT_VALUE(start_in); + uint32_t end = MP_OBJ_SMALL_INT_VALUE(end_in); + return MP_OBJ_NEW_SMALL_INT((end - start) & MP_SMALL_INT_POSITIVE_MASK); +} +MP_DEFINE_CONST_FUN_OBJ_2(mp_utime_ticks_diff_obj, time_ticks_diff); + +#endif // MICROPY_PY_UTIME_MP_HAL diff --git a/extmod/utime_mphal.h b/extmod/utime_mphal.h new file mode 100644 index 000000000..4f2395a09 --- /dev/null +++ b/extmod/utime_mphal.h @@ -0,0 +1,36 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013-2016 Damien P. George + * Copyright (c) 2016 Paul Sokolovsky + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" + +MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_ms_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_sleep_us_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_ms_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_us_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_cpu_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_utime_ticks_diff_obj); diff --git a/py/mpconfig.h b/py/mpconfig.h index e33a41f7a..dcdaffe0f 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -860,6 +860,12 @@ typedef double mp_float_t; #define MICROPY_PY_UERRNO (0) #endif +// Whether to provide "utime" module functions implementation +// in terms of mp_hal_* functions. +#ifndef MICROPY_PY_UTIME_MP_HAL +#define MICROPY_PY_UTIME_MP_HAL (0) +#endif + // Whether to provide "_thread" module #ifndef MICROPY_PY_THREAD #define MICROPY_PY_THREAD (0) diff --git a/py/mphal.h b/py/mphal.h index 54a45b024..8d5654f9e 100644 --- a/py/mphal.h +++ b/py/mphal.h @@ -66,6 +66,10 @@ mp_uint_t mp_hal_ticks_ms(void); mp_uint_t mp_hal_ticks_us(void); #endif +#ifndef mp_hal_ticks_cpu +mp_uint_t mp_hal_ticks_cpu(void); +#endif + // If port HAL didn't define its own pin API, use generic // "virtual pin" API from the core. #ifndef mp_hal_pin_obj_t diff --git a/py/py.mk b/py/py.mk index 741ad52f9..8caa37f8a 100644 --- a/py/py.mk +++ b/py/py.mk @@ -229,6 +229,7 @@ PY_O_BASENAME = \ ../extmod/vfs_fat_file.o \ ../extmod/vfs_fat_lexer.o \ ../extmod/vfs_fat_misc.o \ + ../extmod/utime_mphal.o \ ../extmod/moduos_dupterm.o \ ../lib/embed/abort_.o \ ../lib/utils/printf.o \ -- cgit v1.2.3 From a3edeb9ea5ebd05170af7c1e488724debce41a6f Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 Oct 2016 11:58:57 +1100 Subject: py/objdict: Fix optimisation for allocating result in fromkeys. Iterables don't respond to __len__, so call __len__ on the original argument. --- py/objdict.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'py') diff --git a/py/objdict.c b/py/objdict.c index 7a74557dc..197a1916f 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -250,15 +250,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(dict_copy_obj, dict_copy); // this is a classmethod STATIC mp_obj_t dict_fromkeys(size_t n_args, const mp_obj_t *args) { mp_obj_t iter = mp_getiter(args[1]); - mp_obj_t len = mp_obj_len_maybe(iter); mp_obj_t value = mp_const_none; mp_obj_t next = MP_OBJ_NULL; - mp_obj_t self_out; if (n_args > 2) { value = args[2]; } + // optimisation to allocate result based on len of argument + mp_obj_t self_out; + mp_obj_t len = mp_obj_len_maybe(args[1]); if (len == MP_OBJ_NULL) { /* object's type doesn't have a __len__ slot */ self_out = mp_obj_new_dict(0); -- cgit v1.2.3 From 2750a7b38e0e5f5d2fbcfc28e89de96cd8da978c Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 Oct 2016 12:00:19 +1100 Subject: py/objdict: Actually provide the key that failed in KeyError exception. The failed key is available as exc.args[0], as per CPython. --- py/objdict.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'py') diff --git a/py/objdict.c b/py/objdict.c index 197a1916f..624fc12d4 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -162,7 +162,7 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) { mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP); if (elem == NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "")); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_KeyError, index)); } else { return elem->value; } @@ -178,7 +178,7 @@ STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_dict_t *self = MP_OBJ_TO_PTR(self_in); mp_map_elem_t *elem = mp_map_lookup(&self->map, index, MP_MAP_LOOKUP); if (elem == NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "")); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_KeyError, index)); } else { return elem->value; } @@ -283,7 +283,7 @@ STATIC mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp if (elem == NULL || elem->value == MP_OBJ_NULL) { if (deflt == MP_OBJ_NULL) { if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "")); + nlr_raise(mp_obj_new_exception_arg1(&mp_type_KeyError, key)); } else { value = mp_const_none; } -- cgit v1.2.3 From 7d0d7215d2575a2d36d34c9a13b58cade0610a28 Mon Sep 17 00:00:00 2001 From: Damien George Date: Mon, 17 Oct 2016 12:17:37 +1100 Subject: py: Use mp_raise_msg helper function where appropriate. Saves the following number of bytes of code space: 176 for bare-arm, 352 for minimal, 272 for unix x86-64, 140 for stmhal, 120 for esp8266. --- py/argcheck.c | 11 ++++------- py/bc.c | 5 ++--- py/builtinevex.c | 2 +- py/builtinimport.c | 8 ++++---- py/modbuiltins.c | 9 ++++----- py/modthread.c | 2 +- py/obj.c | 31 +++++++++++-------------------- py/objarray.c | 4 ++-- py/objcomplex.c | 4 ++-- py/objdict.c | 6 ++---- py/objfloat.c | 2 +- py/objgenerator.c | 6 +++--- py/objint.c | 10 +++++----- py/objint_mpz.c | 7 +++---- py/objlist.c | 2 +- py/objnamedtuple.c | 2 +- py/objobject.c | 3 +-- py/objset.c | 4 ++-- py/objstringio.c | 2 +- py/objtype.c | 21 +++++++++------------ py/parsenum.c | 4 ++-- py/runtime.c | 53 +++++++++++++++++++---------------------------------- py/sequence.c | 2 +- py/stream.c | 2 +- 24 files changed, 83 insertions(+), 119 deletions(-) (limited to 'py') diff --git a/py/argcheck.c b/py/argcheck.c index a6c769ee8..8cef10b16 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -37,8 +37,7 @@ void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_ar if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_arg_error_terse_mismatch(); } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "function does not take keyword arguments")); + mp_raise_msg(&mp_type_TypeError, "function does not take keyword arguments"); } } @@ -116,8 +115,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_arg_error_terse_mismatch(); } else { // TODO better error message - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "extra positional arguments given")); + mp_raise_msg(&mp_type_TypeError, "extra positional arguments given"); } } if (kws_found < kws->used) { @@ -125,8 +123,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_arg_error_terse_mismatch(); } else { // TODO better error message - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "extra keyword arguments given")); + mp_raise_msg(&mp_type_TypeError, "extra keyword arguments given"); } } } @@ -139,7 +136,7 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || _MSC_VER NORETURN void mp_arg_error_terse_mismatch(void) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "argument num/types mismatch")); + mp_raise_msg(&mp_type_TypeError, "argument num/types mismatch"); } #endif diff --git a/py/bc.c b/py/bc.c index e5abea244..07de08fc3 100644 --- a/py/bc.c +++ b/py/bc.c @@ -185,7 +185,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, mp_obj_fun_bc_t *self, siz } // Didn't find name match with positional args if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); + mp_raise_msg(&mp_type_TypeError, "function does not take keyword arguments"); } mp_obj_dict_store(dict, kwargs[2 * i], kwargs[2 * i + 1]); continue2:; @@ -234,8 +234,7 @@ continue2:; } else { // no keyword arguments given if (n_kwonly_args != 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "function missing keyword-only argument")); + mp_raise_msg(&mp_type_TypeError, "function missing keyword-only argument"); } if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) != 0) { *var_pos_kw_args = mp_obj_new_dict(0); diff --git a/py/builtinevex.c b/py/builtinevex.c index 74c43b176..636f86930 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -95,7 +95,7 @@ STATIC mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) { case MP_QSTR_exec: parse_input_kind = MP_PARSE_FILE_INPUT; break; case MP_QSTR_eval: parse_input_kind = MP_PARSE_EVAL_INPUT; break; default: - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad compile mode")); + mp_raise_msg(&mp_type_ValueError, "bad compile mode"); } mp_obj_code_t *code = m_new_obj(mp_obj_code_t); diff --git a/py/builtinimport.c b/py/builtinimport.c index e4199f25d..e72eaf472 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -138,7 +138,7 @@ STATIC void do_load_from_lexer(mp_obj_t module_obj, mp_lexer_t *lex, const char if (lex == NULL) { // we verified the file exists using stat, but lexer could still fail if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found")); + mp_raise_msg(&mp_type_ImportError, "module not found"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "no module named '%s'", fname)); @@ -340,7 +340,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { DEBUG_printf("Warning: no dots in current module name and level>0\n"); p = this_name + this_name_l; } else if (level != -1) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "Invalid relative import")); + mp_raise_msg(&mp_type_ImportError, "invalid relative import"); } uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len); @@ -355,7 +355,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q)); if (new_mod_q == MP_QSTR_) { // CPython raises SystemError - nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "cannot perform relative import")); + mp_raise_msg(&mp_type_ImportError, "cannot perform relative import"); } module_name = MP_OBJ_NEW_QSTR(new_mod_q); mod_str = new_mod; @@ -425,7 +425,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #endif // couldn't find the file, so fail if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found")); + mp_raise_msg(&mp_type_ImportError, "module not found"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "no module named '%q'", mod_name)); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 29f84d6c2..57e52efa5 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -178,7 +178,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) { str[3] = (c & 0x3F) | 0x80; len = 4; } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "chr() arg not in range(0x110000)")); + mp_raise_msg(&mp_type_ValueError, "chr() arg not in range(0x110000)"); } return mp_obj_new_str(str, len, true); #else @@ -187,7 +187,7 @@ STATIC mp_obj_t mp_builtin_chr(mp_obj_t o_in) { char str[1] = {ord}; return mp_obj_new_str(str, 1, true); } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "chr() arg not in range(256)")); + mp_raise_msg(&mp_type_ValueError, "chr() arg not in range(256)"); } #endif } @@ -286,7 +286,7 @@ STATIC mp_obj_t mp_builtin_min_max(size_t n_args, const mp_obj_t *args, mp_map_t if (default_elem != NULL) { best_obj = default_elem->value; } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "arg is an empty sequence")); + mp_raise_msg(&mp_type_ValueError, "arg is an empty sequence"); } } return best_obj; @@ -507,8 +507,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum); STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { if (n_args > 1) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "must use keyword argument for key function")); + mp_raise_msg(&mp_type_TypeError, "must use keyword argument for key function"); } mp_obj_t self = mp_type_list.make_new(&mp_type_list, 1, 0, args); mp_obj_list_sort(1, &self, kwargs); diff --git a/py/modthread.c b/py/modthread.c index c358cdf9e..6f55281ad 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -239,7 +239,7 @@ STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) } else { // positional and keyword arguments if (mp_obj_get_type(args[2]) != &mp_type_dict) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "expecting a dict for keyword args")); + mp_raise_msg(&mp_type_TypeError, "expecting a dict for keyword args"); } mp_map_t *map = &((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[2]))->map; th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used); diff --git a/py/obj.c b/py/obj.c index d6ce3dae6..72b7a216b 100644 --- a/py/obj.c +++ b/py/obj.c @@ -233,8 +233,7 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) { return mp_obj_int_get_checked(arg); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "can't convert to int")); + mp_raise_msg(&mp_type_TypeError, "can't convert to int"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg))); @@ -282,8 +281,7 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) { return mp_obj_float_get(arg); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "can't convert to float")); + mp_raise_msg(&mp_type_TypeError, "can't convert to float"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg))); @@ -312,8 +310,7 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { mp_obj_complex_get(arg, real, imag); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "can't convert to complex")); + mp_raise_msg(&mp_type_TypeError, "can't convert to complex"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg))); @@ -331,8 +328,7 @@ void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) { mp_obj_list_get(o, len, items); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "expected tuple/list")); + mp_raise_msg(&mp_type_TypeError, "expected tuple/list"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); @@ -346,8 +342,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items) { mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, - "tuple/list has wrong length")); + mp_raise_msg(&mp_type_ValueError, "tuple/list has wrong length"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "requested length %d but object has length %d", (int)len, (int)seq_len)); @@ -362,8 +357,7 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index, i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "indices must be integers")); + mp_raise_msg(&mp_type_TypeError, "indices must be integers"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%q indices must be integers, not %s", @@ -383,7 +377,7 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index, } else { if (i < 0 || (mp_uint_t)i >= len) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "index out of range")); + mp_raise_msg(&mp_type_IndexError, "index out of range"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "%q index out of range", type->name)); @@ -416,8 +410,7 @@ mp_obj_t mp_obj_len(mp_obj_t o_in) { mp_obj_t len = mp_obj_len_maybe(o_in); if (len == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object has no len")); + mp_raise_msg(&mp_type_TypeError, "object has no len"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in))); @@ -458,8 +451,7 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { } if (value == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object does not support item deletion")); + mp_raise_msg(&mp_type_TypeError, "object does not support item deletion"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item deletion", mp_obj_get_type_str(base))); @@ -474,8 +466,7 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object does not support item assignment")); + mp_raise_msg(&mp_type_TypeError, "object does not support item assignment"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item assignment", mp_obj_get_type_str(base))); @@ -504,7 +495,7 @@ bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { if (!mp_get_buffer(obj, bufinfo, flags)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "object with buffer protocol required")); + mp_raise_msg(&mp_type_TypeError, "object with buffer protocol required"); } } diff --git a/py/objarray.c b/py/objarray.c index 2cd0fef6b..8e1d32f0f 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -95,7 +95,7 @@ STATIC void array_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t STATIC mp_obj_array_t *array_new(char typecode, mp_uint_t n) { int typecode_size = mp_binary_get_size('@', typecode, NULL); if (typecode_size == 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad typecode")); + mp_raise_msg(&mp_type_ValueError, "bad typecode"); } mp_obj_array_t *o = m_new_obj(mp_obj_array_t); #if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_PY_ARRAY @@ -395,7 +395,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value); if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) { compat_error: - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "lhs and rhs should be compatible")); + mp_raise_msg(&mp_type_ValueError, "lhs and rhs should be compatible"); } src_len = src_slice->len; src_items = src_slice->items; diff --git a/py/objcomplex.c b/py/objcomplex.c index 5da655eb3..96be25255 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -197,7 +197,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t case MP_BINARY_OP_INPLACE_TRUE_DIVIDE: if (rhs_imag == 0) { if (rhs_real == 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "complex division by zero")); + mp_raise_msg(&mp_type_ZeroDivisionError, "complex division by zero"); } lhs_real /= rhs_real; lhs_imag /= rhs_real; @@ -226,7 +226,7 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t lhs_real = 1; rhs_real = 0; } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power")); + mp_raise_msg(&mp_type_ZeroDivisionError, "0.0 to a complex power"); } } else { mp_float_t ln1 = MICROPY_FLOAT_C_FUN(log)(abs1); diff --git a/py/objdict.c b/py/objdict.c index 624fc12d4..4942d3779 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -343,7 +343,7 @@ STATIC mp_obj_t dict_popitem(mp_obj_t self_in) { mp_uint_t cur = 0; mp_map_elem_t *next = dict_iter_next(self, &cur); if (next == NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "popitem(): dictionary is empty")); + mp_raise_msg(&mp_type_KeyError, "popitem(): dictionary is empty"); } self->map.used--; mp_obj_t items[] = {next->key, next->value}; @@ -385,9 +385,7 @@ STATIC mp_obj_t dict_update(size_t n_args, const mp_obj_t *args, mp_map_t *kwarg 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")); + mp_raise_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; } diff --git a/py/objfloat.c b/py/objfloat.c index 85b8b1386..73d07feac 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -198,7 +198,7 @@ mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs_i case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: if (rhs_val == 0) { zero_division_error: - nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero")); + mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); } // Python specs require that x == (x//y)*y + (x%y) so we must // call divmod to compute the correct floor division, which diff --git a/py/objgenerator.c b/py/objgenerator.c index 8c32a3649..cbef9fea3 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -105,7 +105,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_ } if (self->code_state.sp == self->code_state.state - 1) { if (send_value != mp_const_none) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "can't send non-None value to a just-started generator")); + mp_raise_msg(&mp_type_TypeError, "can't send non-None value to a just-started generator"); } } else { *self->code_state.sp = send_value; @@ -157,7 +157,7 @@ STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_o case MP_VM_RETURN_YIELD: if (throw_value != MP_OBJ_NULL && mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(throw_value)), MP_OBJ_FROM_PTR(&mp_type_GeneratorExit))) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit")); + mp_raise_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit"); } return ret; @@ -209,7 +209,7 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) { mp_obj_t ret; switch (mp_obj_gen_resume(self_in, mp_const_none, MP_OBJ_FROM_PTR(&mp_const_GeneratorExit_obj), &ret)) { case MP_VM_RETURN_YIELD: - nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit")); + mp_raise_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit"); // Swallow StopIteration & GeneratorExit (== successful close), and re-raise any other case MP_VM_RETURN_EXCEPTION: diff --git a/py/objint.c b/py/objint.c index 49dec0653..f8988d6c9 100644 --- a/py/objint.c +++ b/py/objint.c @@ -294,19 +294,19 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { // This is called only with strings whose value doesn't fit in SMALL_INT mp_obj_t mp_obj_new_int_from_str_len(const char **str, mp_uint_t len, bool neg, mp_uint_t base) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "long int not supported in this build")); + mp_raise_msg(&mp_type_OverflowError, "long int not supported in this build"); return mp_const_none; } // This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT) mp_obj_t mp_obj_new_int_from_ll(long long val) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow")); + mp_raise_msg(&mp_type_OverflowError, "small int overflow"); return mp_const_none; } // This is called when an integer larger than a SMALL_INT is needed (although val might still fit in a SMALL_INT) mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow")); + mp_raise_msg(&mp_type_OverflowError, "small int overflow"); return mp_const_none; } @@ -316,7 +316,7 @@ mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) { if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) { return MP_OBJ_NEW_SMALL_INT(value); } - nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow")); + mp_raise_msg(&mp_type_OverflowError, "small int overflow"); return mp_const_none; } @@ -342,7 +342,7 @@ mp_obj_t mp_obj_new_int(mp_int_t value) { if (MP_SMALL_INT_FITS(value)) { return MP_OBJ_NEW_SMALL_INT(value); } - nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "small int overflow")); + mp_raise_msg(&mp_type_OverflowError, "small int overflow"); return mp_const_none; } diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 6a59133d7..0a1d68598 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -234,8 +234,7 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: { if (mpz_is_zero(zrhs)) { zero_division_error: - nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, - "division by zero")); + mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); } mpz_t rem; mpz_init_zero(&rem); mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs); @@ -272,7 +271,7 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { case MP_BINARY_OP_INPLACE_RSHIFT: { mp_int_t irhs = mp_obj_int_get_checked(rhs_in); if (irhs < 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count")); + mp_raise_msg(&mp_type_ValueError, "negative shift count"); } if (op == MP_BINARY_OP_LSHIFT || op == MP_BINARY_OP_INPLACE_LSHIFT) { mpz_shl_inpl(&res->mpz, zlhs, irhs); @@ -398,7 +397,7 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { return value; } else { // overflow - nlr_raise(mp_obj_new_exception_msg(&mp_type_OverflowError, "overflow converting long int to machine word")); + mp_raise_msg(&mp_type_OverflowError, "overflow converting long int to machine word"); } } } diff --git a/py/objlist.c b/py/objlist.c index b5e8b9965..6d4a20a50 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -266,7 +266,7 @@ STATIC mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) { mp_check_self(MP_OBJ_IS_TYPE(args[0], &mp_type_list)); mp_obj_list_t *self = MP_OBJ_TO_PTR(args[0]); if (self->len == 0) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "pop from empty list")); + mp_raise_msg(&mp_type_IndexError, "pop from empty list"); } mp_uint_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false); mp_obj_t ret = self->items[index]; diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index 38cda1ad7..18931a16c 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -73,7 +73,7 @@ STATIC void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } else { // delete/store attribute // provide more detailed error message than we'd get by just returning - nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "can't set attribute")); + mp_raise_msg(&mp_type_AttributeError, "can't set attribute"); } } diff --git a/py/objobject.c b/py/objobject.c index bba6f053e..b33dc491c 100644 --- a/py/objobject.c +++ b/py/objobject.c @@ -50,8 +50,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(object___init___obj, object___init__); STATIC mp_obj_t object___new__(mp_obj_t cls) { if (!MP_OBJ_IS_TYPE(cls, &mp_type_type) || !mp_obj_is_instance_type((mp_obj_type_t*)MP_OBJ_TO_PTR(cls))) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "__new__ arg must be a user-type")); + mp_raise_msg(&mp_type_TypeError, "__new__ arg must be a user-type"); } mp_obj_t o = MP_OBJ_SENTINEL; mp_obj_t res = mp_obj_instance_make_new(MP_OBJ_TO_PTR(cls), 1, 0, &o); diff --git a/py/objset.c b/py/objset.c index 6b6f95f9b..fc124fcd8 100644 --- a/py/objset.c +++ b/py/objset.c @@ -68,7 +68,7 @@ STATIC void check_set(mp_obj_t o) { if (MP_OBJ_IS_TYPE(o, &mp_type_frozenset)) { // Mutable method called on frozenset; emulate CPython behavior, eg: // AttributeError: 'frozenset' object has no attribute 'add' - nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "'frozenset' has no such attribute")); + mp_raise_msg(&mp_type_AttributeError, "'frozenset' has no such attribute"); } #endif mp_check_self(MP_OBJ_IS_TYPE(o, &mp_type_set)); @@ -389,7 +389,7 @@ STATIC mp_obj_t set_pop(mp_obj_t self_in) { mp_obj_set_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t obj = mp_set_remove_first(&self->set); if (obj == MP_OBJ_NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_KeyError, "pop from an empty set")); + mp_raise_msg(&mp_type_KeyError, "pop from an empty set"); } return obj; } diff --git a/py/objstringio.c b/py/objstringio.c index 212d8e314..a430fca3b 100644 --- a/py/objstringio.c +++ b/py/objstringio.c @@ -39,7 +39,7 @@ #if MICROPY_CPYTHON_COMPAT STATIC void check_stringio_is_open(const mp_obj_stringio_t *o) { if (o->vstr == NULL) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "I/O operation on closed file")); + mp_raise_msg(&mp_type_ValueError, "I/O operation on closed file"); } } #else diff --git a/py/objtype.c b/py/objtype.c index 907308a75..8b46c5400 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -311,8 +311,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size } if (init_ret != mp_const_none) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "__init__() should return None")); + mp_raise_msg(&mp_type_TypeError, "__init__() should return None"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret))); @@ -508,7 +507,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des // the code. const mp_obj_t *proxy = mp_obj_property_get(member); if (proxy[0] == mp_const_none) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "unreadable attribute")); + mp_raise_msg(&mp_type_AttributeError, "unreadable attribute"); } else { dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self_in); } @@ -710,8 +709,7 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons mp_obj_t call = mp_obj_instance_get_call(self_in); if (call == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object not callable")); + mp_raise_msg(&mp_type_TypeError, "object not callable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(self_in))); @@ -793,7 +791,7 @@ STATIC mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_ return mp_obj_new_type(mp_obj_str_get_qstr(args[0]), args[1], args[2]); default: - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "type takes 1 or 3 arguments")); + mp_raise_msg(&mp_type_TypeError, "type takes 1 or 3 arguments"); } } @@ -804,7 +802,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp if (self->make_new == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "cannot create instance")); + mp_raise_msg(&mp_type_TypeError, "cannot create instance"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "cannot create '%q' instances", self->name)); @@ -892,8 +890,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // TODO: Verify with CPy, tested on function type if (t->make_new == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "type is not an acceptable base type")); + mp_raise_msg(&mp_type_TypeError, "type is not an acceptable base type"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "type '%q' is not an acceptable base type", t->name)); @@ -927,7 +924,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) const mp_obj_type_t *native_base; uint num_native_bases = instance_count_native_bases(o, &native_base); if (num_native_bases > 1) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict")); + mp_raise_msg(&mp_type_TypeError, "multiple bases have instance lay-out conflict"); } mp_map_t *locals_map = &o->locals_dict->map; @@ -1074,7 +1071,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { } else if (MP_OBJ_IS_TYPE(classinfo, &mp_type_tuple)) { mp_obj_tuple_get(classinfo, &len, &items); } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "issubclass() arg 2 must be a class or a tuple of classes")); + mp_raise_msg(&mp_type_TypeError, "issubclass() arg 2 must be a class or a tuple of classes"); } for (uint i = 0; i < len; i++) { @@ -1088,7 +1085,7 @@ STATIC mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo) { STATIC mp_obj_t mp_builtin_issubclass(mp_obj_t object, mp_obj_t classinfo) { if (!MP_OBJ_IS_TYPE(object, &mp_type_type)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "issubclass() arg 1 must be a class")); + mp_raise_msg(&mp_type_TypeError, "issubclass() arg 1 must be a class"); } return mp_obj_is_subclass(object, classinfo); } diff --git a/py/parsenum.c b/py/parsenum.c index 83a6abd20..1010ad305 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -27,7 +27,7 @@ #include #include -#include "py/nlr.h" +#include "py/runtime.h" #include "py/parsenumbase.h" #include "py/parsenum.h" #include "py/smallint.h" @@ -55,7 +55,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m // check radix base if ((base != 0 && base < 2) || base > 36) { // this won't be reached if lex!=NULL - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "int() arg 2 must be >= 2 and <= 36")); + mp_raise_msg(&mp_type_ValueError, "int() arg 2 must be >= 2 and <= 36"); } // skip leading space diff --git a/py/runtime.c b/py/runtime.c index 003c9f8b4..6eda77ee9 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -138,8 +138,7 @@ mp_obj_t mp_load_global(qstr qst) { elem = mp_map_lookup((mp_map_t*)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); if (elem == NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_NameError, - "name not defined")); + mp_raise_msg(&mp_type_NameError, "name not defined"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError, "name '%q' is not defined", qst)); @@ -230,8 +229,7 @@ mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) { } } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "unsupported type for operator")); + mp_raise_msg(&mp_type_TypeError, "unsupported type for operator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported type for %q: '%s'", @@ -323,7 +321,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_LSHIFT: { if (rhs_val < 0) { // negative shift not allowed - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count")); + mp_raise_msg(&mp_type_ValueError, "negative shift count"); } else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) { // left-shift will overflow, so use higher precision integer lhs = mp_obj_new_int_from_ll(lhs_val); @@ -338,7 +336,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_RSHIFT: if (rhs_val < 0) { // negative shift not allowed - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative shift count")); + mp_raise_msg(&mp_type_ValueError, "negative shift count"); } else { // standard precision is enough for right-shift if (rhs_val >= (mp_int_t)BITS_PER_WORD) { @@ -414,7 +412,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { lhs = mp_obj_new_float(lhs_val); goto generic_binary_op; #else - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "negative power with no float support")); + mp_raise_msg(&mp_type_ValueError, "negative power with no float support"); #endif } else { mp_int_t ans = 1; @@ -515,8 +513,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object not iterable")); + mp_raise_msg(&mp_type_TypeError, "object not iterable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(rhs))); @@ -538,8 +535,7 @@ generic_binary_op: unsupported_op: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "unsupported type for operator")); + mp_raise_msg(&mp_type_TypeError, "unsupported type for operator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported types for %q: '%s', '%s'", @@ -547,7 +543,7 @@ unsupported_op: } zero_division: - nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero")); + mp_raise_msg(&mp_type_ZeroDivisionError, "division by zero"); } mp_obj_t mp_call_function_0(mp_obj_t fun) { @@ -581,8 +577,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args, mp_uint_t n_kw } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object not callable")); + mp_raise_msg(&mp_type_TypeError, "object not callable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(fun_in))); @@ -813,16 +808,14 @@ void mp_unpack_sequence(mp_obj_t seq_in, mp_uint_t num, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, - "wrong number of values to unpack")); + mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len)); } too_long: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, - "wrong number of values to unpack")); + mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", (int)num)); @@ -888,8 +881,7 @@ void mp_unpack_ex(mp_obj_t seq_in, mp_uint_t num_in, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, - "wrong number of values to unpack")); + mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len)); @@ -928,8 +920,7 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]); if (arg0_type != self->type) { if (MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "argument has wrong type")); + mp_raise_msg(&mp_type_TypeError, "argument has wrong type"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "argument should be a '%q' not a '%q'", self->type->name, arg0_type->name)); @@ -1045,8 +1036,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // no attribute/method called attr if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, - "no such attribute")); + mp_raise_msg(&mp_type_AttributeError, "no such attribute"); } else { // following CPython, we give a more detailed error message for type objects if (MP_OBJ_IS_TYPE(base, &mp_type_type)) { @@ -1074,8 +1064,7 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { } } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, - "no such attribute")); + mp_raise_msg(&mp_type_AttributeError, "no such attribute"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, "'%s' object has no attribute '%q'", @@ -1105,8 +1094,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in) { // object not iterable if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object not iterable")); + mp_raise_msg(&mp_type_TypeError, "object not iterable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(o_in))); @@ -1128,8 +1116,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { return mp_call_method_n_kw(0, 0, dest); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object not an iterator")); + mp_raise_msg(&mp_type_TypeError, "object not an iterator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); @@ -1165,8 +1152,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "object not an iterator")); + mp_raise_msg(&mp_type_TypeError, "object not an iterator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); @@ -1384,8 +1370,7 @@ void *m_malloc_fail(size_t num_bytes) { // dummy #if MICROPY_ENABLE_GC } else if (gc_is_locked()) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_MemoryError, - "memory allocation failed, heap is locked")); + mp_raise_msg(&mp_type_MemoryError, "memory allocation failed, heap is locked"); #endif } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError, diff --git a/py/sequence.c b/py/sequence.c index 239f1b2cc..0acdd25be 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -235,7 +235,7 @@ mp_obj_t mp_seq_index_obj(const mp_obj_t *items, mp_uint_t len, mp_uint_t n_args } } - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "object not in sequence")); + mp_raise_msg(&mp_type_ValueError, "object not in sequence"); } mp_obj_t mp_seq_count_obj(const mp_obj_t *items, mp_uint_t len, mp_obj_t value) { diff --git a/py/stream.c b/py/stream.c index 5610faf74..cc8a63ac2 100644 --- a/py/stream.c +++ b/py/stream.c @@ -101,7 +101,7 @@ const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) { || ((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL) || ((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) { // CPython: io.UnsupportedOperation, OSError subclass - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "stream operation not supported")); + mp_raise_msg(&mp_type_OSError, "stream operation not supported"); } return stream_p; } -- cgit v1.2.3 From b440307b4a15a540413a7a9f699d388c7428a63c Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Fri, 21 Oct 2016 01:08:43 +0300 Subject: py/py.mk: Automatically add frozen.c to source list if FROZEN_DIR is defined. Now frozen modules generation handled fully by py.mk and available for reuse by any port. --- esp8266/Makefile | 6 +++--- py/py.mk | 4 ++++ zephyr/Makefile | 1 - 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'py') diff --git a/esp8266/Makefile b/esp8266/Makefile index c57206c4d..5f0044df0 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -7,14 +7,15 @@ MICROPY_PY_USSL = 1 MICROPY_SSL_AXTLS = 1 MICROPY_PY_BTREE = 1 +FROZEN_DIR = scripts +FROZEN_MPY_DIR = modules + # include py core make definitions include ../py/py.mk MPY_CROSS = ../mpy-cross/mpy-cross MPY_TOOL = ../tools/mpy-tool.py -FROZEN_DIR = scripts -FROZEN_MPY_DIR = modules PORT ?= /dev/ttyACM0 BAUD ?= 115200 FLASH_MODE ?= qio @@ -90,7 +91,6 @@ SRC_C = \ modmachine.c \ modonewire.c \ ets_alt_task.c \ - $(BUILD)/frozen.c \ fatfs_port.c \ axtls_helpers.c \ hspi.c \ diff --git a/py/py.mk b/py/py.mk index 8caa37f8a..ab07bbbde 100644 --- a/py/py.mk +++ b/py/py.mk @@ -237,6 +237,10 @@ PY_O_BASENAME = \ # prepend the build destination prefix to the py object files PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME)) +ifneq ($(FROZEN_DIR),) +PY_O += $(BUILD)/$(BUILD)/frozen.o +endif + # Sources that may contain qstrings SRC_QSTR_IGNORE = nlr% emitnx% emitnthumb% emitnarm% SRC_QSTR = $(SRC_MOD) $(addprefix py/,$(filter-out $(SRC_QSTR_IGNORE),$(PY_O_BASENAME:.o=.c)) emitnative.c) diff --git a/zephyr/Makefile b/zephyr/Makefile index 1db84cb32..9682dc5cc 100644 --- a/zephyr/Makefile +++ b/zephyr/Makefile @@ -41,7 +41,6 @@ SRC_C = main.c \ lib/utils/interrupt_char.c \ lib/utils/pyhelp.c \ lib/mp-readline/readline.c \ - $(BUILD)/frozen.c \ $(SRC_MOD) # List of sources for qstr extraction -- cgit v1.2.3