diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/builtin.h | 97 | ||||
-rw-r--r-- | py/emitbc.c | 5 | ||||
-rw-r--r-- | py/mkenv.mk | 2 | ||||
-rw-r--r-- | py/mkrules.mk | 17 | ||||
-rw-r--r-- | py/modbuiltins.c | 22 | ||||
-rw-r--r-- | py/modmath.c | 9 | ||||
-rw-r--r-- | py/mpconfig.h | 15 | ||||
-rw-r--r-- | py/mpprint.h | 6 | ||||
-rw-r--r-- | py/mpz.c | 5 | ||||
-rw-r--r-- | py/nlrx86.S | 34 | ||||
-rw-r--r-- | py/obj.c | 6 | ||||
-rw-r--r-- | py/obj.h | 63 | ||||
-rw-r--r-- | py/objfun.c | 86 | ||||
-rw-r--r-- | py/objstr.h | 54 | ||||
-rw-r--r-- | py/parse.c | 5 | ||||
-rw-r--r-- | py/parsenum.c | 2 | ||||
-rw-r--r-- | py/py.mk | 12 | ||||
-rw-r--r-- | py/qstr.c | 2 | ||||
-rw-r--r-- | py/runtime.c | 8 | ||||
-rw-r--r-- | py/sequence.c | 49 | ||||
-rw-r--r-- | py/stream.c | 2 | ||||
-rw-r--r-- | py/stream.h | 24 | ||||
-rw-r--r-- | py/warning.c | 1 |
23 files changed, 337 insertions, 189 deletions
diff --git a/py/builtin.h b/py/builtin.h index cd1be3ab88..4477fd2462 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -32,56 +32,56 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args); mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs); mp_obj_t mp_micropython_mem_info(size_t n_args, const mp_obj_t *args); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin___build_class___obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin___import___obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin___repl_print___obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_abs_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_all_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_any_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_bin_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_callable_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_compile_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_chr_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_dir_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_divmod_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_eval_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_exec_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_execfile_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_getattr_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_setattr_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_globals_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hasattr_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hash_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_hex_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_id_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_isinstance_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_issubclass_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_iter_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_len_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_list_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_locals_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_max_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_min_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_next_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_oct_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_ord_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_pow_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_print_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_repr_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_round_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sorted_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR(mp_builtin___build_class___obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin___import___obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin___repl_print___obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_abs_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_all_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_any_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_bin_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_callable_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_compile_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_chr_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_builtin_delattr_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_dir_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_builtin_divmod_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_eval_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_exec_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_execfile_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_getattr_obj); +MP_DECLARE_CONST_FUN_OBJ_3(mp_builtin_setattr_obj); +MP_DECLARE_CONST_FUN_OBJ_0(mp_builtin_globals_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_builtin_hasattr_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_hash_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_hex_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_id_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_builtin_isinstance_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_builtin_issubclass_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_iter_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_len_obj); +MP_DECLARE_CONST_FUN_OBJ_0(mp_builtin_locals_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_max_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_min_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_next_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_oct_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_ord_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_pow_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_print_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_builtin_repr_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_round_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_sorted_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj); // Defined by a port, but declared here for simplicity -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_help_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_input_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_builtin_open_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_namedtuple_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_op_contains_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_op_getitem_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_op_setitem_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_op_delitem_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_op_contains_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_op_getitem_obj); +MP_DECLARE_CONST_FUN_OBJ_3(mp_op_setitem_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_op_delitem_obj); extern const mp_obj_module_t mp_module___main__; extern const mp_obj_module_t mp_module_builtins; @@ -116,7 +116,4 @@ extern const mp_obj_module_t mp_module_webrepl; extern const mp_obj_module_t mp_module_framebuf; extern const mp_obj_module_t mp_module_btree; -// extmod functions -MP_DECLARE_CONST_FUN_OBJ(pyb_mount_obj); - #endif // __MICROPY_INCLUDED_PY_BUILTIN_H__ diff --git a/py/emitbc.c b/py/emitbc.c index d6f2bf333c..e11c9ae94f 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -183,7 +183,6 @@ STATIC void emit_write_bytecode_byte(emit_t *emit, byte b1) { } STATIC void emit_write_bytecode_byte_byte(emit_t* emit, byte b1, byte b2) { - assert((b2 & (~0xff)) == 0); byte *c = emit_get_cur_to_write_bytecode(emit, 2); c[0] = b1; c[1] = b2; @@ -550,7 +549,6 @@ void mp_emit_bc_load_null(emit_t *emit) { void mp_emit_bc_load_fast(emit_t *emit, qstr qst, mp_uint_t local_num) { (void)qst; - assert(local_num >= 0); emit_bc_pre(emit, 1); if (local_num <= 15) { emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_MULTI + local_num); @@ -608,7 +606,6 @@ void mp_emit_bc_load_subscr(emit_t *emit) { void mp_emit_bc_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num) { (void)qst; - assert(local_num >= 0); emit_bc_pre(emit, -1); if (local_num <= 15) { emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_MULTI + local_num); @@ -927,7 +924,7 @@ void mp_emit_bc_return_value(emit_t *emit) { } void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) { - assert(0 <= n_args && n_args <= 2); + assert(n_args <= 2); emit_bc_pre(emit, -n_args); emit_write_bytecode_byte_byte(emit, MP_BC_RAISE_VARARGS, n_args); } diff --git a/py/mkenv.mk b/py/mkenv.mk index e7262907c8..14e23e074c 100644 --- a/py/mkenv.mk +++ b/py/mkenv.mk @@ -59,6 +59,8 @@ LD += -m32 endif MAKE_FROZEN = ../tools/make-frozen.py +MPY_CROSS = ../mpy-cross/mpy-cross +MPY_TOOL = ../tools/mpy-tool.py all: .PHONY: all diff --git a/py/mkrules.mk b/py/mkrules.mk index 26e4aeab3f..ea647e86f8 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -106,6 +106,23 @@ $(BUILD)/frozen.c: $(wildcard $(FROZEN_DIR)/*) $(HEADER_BUILD) $(FROZEN_EXTRA_DE $(Q)$(MAKE_FROZEN) $(FROZEN_DIR) > $@ endif +ifneq ($(FROZEN_MPY_DIR),) +# make a list of all the .py files that need compiling and freezing +FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py' -printf '%P\n') +FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/frozen_mpy/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) + +# to build .mpy files from .py files +$(BUILD)/frozen_mpy/%.mpy: $(FROZEN_MPY_DIR)/%.py + @$(ECHO) "MPY $<" + $(Q)$(MKDIR) -p $(dir $@) + $(Q)$(MPY_CROSS) -o $@ -s $(^:$(FROZEN_MPY_DIR)/%=%) $^ + +# to build frozen_mpy.c from all .mpy files +$(BUILD)/frozen_mpy.c: $(FROZEN_MPY_MPY_FILES) $(BUILD)/genhdr/qstrdefs.generated.h + @$(ECHO) "Creating $@" + $(Q)$(PYTHON) $(MPY_TOOL) -f -q $(BUILD)/genhdr/qstrdefs.preprocessed.h $(FROZEN_MPY_MPY_FILES) > $@ +endif + ifneq ($(PROG),) # Build a standalone executable (unix does this) diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 57e52efa52..cbdcc9aae0 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -430,13 +430,8 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_print_obj, 0, mp_builtin_print); STATIC mp_obj_t mp_builtin___repl_print__(mp_obj_t o) { if (o != mp_const_none) { - #if MICROPY_PY_IO - mp_obj_print_helper(&mp_sys_stdout_print, o, PRINT_REPR); - mp_print_str(&mp_sys_stdout_print, "\n"); - #else - mp_obj_print_helper(&mp_plat_print, o, PRINT_REPR); - mp_print_str(&mp_plat_print, "\n"); - #endif + mp_obj_print_helper(MP_PYTHON_PRINTER, o, PRINT_REPR); + mp_print_str(MP_PYTHON_PRINTER, "\n"); #if MICROPY_CAN_OVERRIDE_BUILTINS // Set "_" special variable mp_obj_t dest[2] = {MP_OBJ_SENTINEL, o}; @@ -547,6 +542,13 @@ STATIC mp_obj_t mp_builtin_setattr(mp_obj_t base, mp_obj_t attr, mp_obj_t value) } MP_DEFINE_CONST_FUN_OBJ_3(mp_builtin_setattr_obj, mp_builtin_setattr); +#if MICROPY_CPYTHON_COMPAT +STATIC mp_obj_t mp_builtin_delattr(mp_obj_t base, mp_obj_t attr) { + return mp_builtin_setattr(base, attr, MP_OBJ_NULL); +} +MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_delattr_obj, mp_builtin_delattr); +#endif + STATIC mp_obj_t mp_builtin_hasattr(mp_obj_t object_in, mp_obj_t attr_in) { qstr attr = mp_obj_str_get_qstr(attr_in); @@ -622,6 +624,9 @@ STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = { #if MICROPY_PY_BUILTINS_SET { MP_ROM_QSTR(MP_QSTR_set), MP_ROM_PTR(&mp_type_set) }, #endif + #if MICROPY_PY_BUILTINS_SLICE + { MP_ROM_QSTR(MP_QSTR_slice), MP_ROM_PTR(&mp_type_slice) }, + #endif { MP_ROM_QSTR(MP_QSTR_str), MP_ROM_PTR(&mp_type_str) }, { MP_ROM_QSTR(MP_QSTR_super), MP_ROM_PTR(&mp_type_super) }, { MP_ROM_QSTR(MP_QSTR_tuple), MP_ROM_PTR(&mp_type_tuple) }, @@ -647,6 +652,9 @@ STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mp_builtin_compile_obj) }, #endif { MP_ROM_QSTR(MP_QSTR_chr), MP_ROM_PTR(&mp_builtin_chr_obj) }, + #if MICROPY_CPYTHON_COMPAT + { MP_ROM_QSTR(MP_QSTR_delattr), MP_ROM_PTR(&mp_builtin_delattr_obj) }, + #endif { MP_ROM_QSTR(MP_QSTR_dir), MP_ROM_PTR(&mp_builtin_dir_obj) }, { MP_ROM_QSTR(MP_QSTR_divmod), MP_ROM_PTR(&mp_builtin_divmod_obj) }, #if MICROPY_PY_BUILTINS_EVAL_EXEC diff --git a/py/modmath.c b/py/modmath.c index 0c70f34cd1..7c51eab03a 100644 --- a/py/modmath.c +++ b/py/modmath.c @@ -32,9 +32,8 @@ #include <math.h> // M_PI is not part of the math.h standard and may not be defined -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif +// And by defining our own we can ensure it uses the correct const format. +#define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846) /// \module math - mathematical functions /// @@ -204,13 +203,13 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_modf_obj, mp_math_modf); /// \function radians(x) STATIC mp_obj_t mp_math_radians(mp_obj_t x_obj) { - return mp_obj_new_float(mp_obj_get_float(x_obj) * M_PI / 180.0); + return mp_obj_new_float(mp_obj_get_float(x_obj) * (MP_PI / MICROPY_FLOAT_CONST(180.0))); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_radians_obj, mp_math_radians); /// \function degrees(x) STATIC mp_obj_t mp_math_degrees(mp_obj_t x_obj) { - return mp_obj_new_float(mp_obj_get_float(x_obj) * 180.0 / M_PI); + return mp_obj_new_float(mp_obj_get_float(x_obj) * (MICROPY_FLOAT_CONST(180.0) / MP_PI)); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_degrees_obj, mp_math_degrees); diff --git a/py/mpconfig.h b/py/mpconfig.h index dcdaffe0f4..3945a1a5ab 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -110,10 +110,11 @@ // Be conservative and always clear to zero newly (re)allocated memory in the GC. // This helps eliminate stray pointers that hold on to memory that's no longer // used. It decreases performance due to unnecessary memory clearing. +// A memory manager which always clears memory can set this to 0. // TODO Do analysis to understand why some memory is not properly cleared and // find a more efficient way to clear it. #ifndef MICROPY_GC_CONSERVATIVE_CLEAR -#define MICROPY_GC_CONSERVATIVE_CLEAR (1) +#define MICROPY_GC_CONSERVATIVE_CLEAR (MICROPY_ENABLE_GC) #endif // Support automatic GC when reaching allocation threshold, @@ -504,10 +505,12 @@ typedef long long mp_longint_impl_t; #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT #define MICROPY_PY_BUILTINS_FLOAT (1) +#define MICROPY_FLOAT_CONST(x) x##F #define MICROPY_FLOAT_C_FUN(fun) fun##f typedef float mp_float_t; #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE #define MICROPY_PY_BUILTINS_FLOAT (1) +#define MICROPY_FLOAT_CONST(x) x #define MICROPY_FLOAT_C_FUN(fun) fun typedef double mp_float_t; #else @@ -866,6 +869,16 @@ typedef double mp_float_t; #define MICROPY_PY_UTIME_MP_HAL (0) #endif +// Period of values returned by utime.ticks_ms(), ticks_us(), ticks_cpu() +// functions. Should be power of two. All functions above use the same +// period, so if underlying hardware/API has different periods, the +// minimum of them should be used. The value below is the maximum value +// this parameter can take (corresponding to 30 bit tick values on 32-bit +// system). +#ifndef MICROPY_PY_UTIME_TICKS_PERIOD +#define MICROPY_PY_UTIME_TICKS_PERIOD (MP_SMALL_INT_POSITIVE_MASK + 1) +#endif + // Whether to provide "_thread" module #ifndef MICROPY_PY_THREAD #define MICROPY_PY_THREAD (0) diff --git a/py/mpprint.h b/py/mpprint.h index 6e47409ecc..f9204e322d 100644 --- a/py/mpprint.h +++ b/py/mpprint.h @@ -39,6 +39,12 @@ #define PF_FLAG_ADD_PERCENT (0x100) #define PF_FLAG_SHOW_OCTAL_LETTER (0x200) +#if MICROPY_PY_IO +# define MP_PYTHON_PRINTER &mp_sys_stdout_print +#else +# define MP_PYTHON_PRINTER &mp_plat_print +#endif + typedef void (*mp_print_strn_t)(void *data, const char *str, size_t len); typedef struct _mp_print_t { @@ -1652,7 +1652,10 @@ char *mpz_as_str(const mpz_t *i, mp_uint_t base) { // 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) { + if (str == NULL) { + return 0; + } + if (base < 2 || base > 32) { str[0] = 0; return 0; } diff --git a/py/nlrx86.S b/py/nlrx86.S index 8a96af81ce..8c538ba176 100644 --- a/py/nlrx86.S +++ b/py/nlrx86.S @@ -37,9 +37,18 @@ #if defined(_WIN32) || defined(__CYGWIN__) #define NLR_OS_WINDOWS +#endif + +#if defined(__APPLE__) && defined(__MACH__) +#define NLR_OS_MAC +#endif + +#if defined(NLR_OS_WINDOWS) || defined(NLR_OS_MAC) #define NLR_TOP (_mp_state_ctx + NLR_TOP_OFFSET) +#define MP_THREAD_GET_STATE _mp_thread_get_state #else #define NLR_TOP (mp_state_ctx + NLR_TOP_OFFSET) +#define MP_THREAD_GET_STATE mp_thread_get_state #endif // offset of nlr_top within mp_state_thread_t structure @@ -55,6 +64,9 @@ .globl _nlr_push .def _nlr_push; .scl 2; .type 32; .endef _nlr_push: +#elif defined(NLR_OS_MAC) + .globl _nlr_push +_nlr_push: #else .globl nlr_push .type nlr_push, @function @@ -75,7 +87,7 @@ nlr_push: mov %edx, NLR_TOP # stor new nlr_buf (to make linked list) #else // to check: stack is aligned to 16-byte boundary before this call - call mp_thread_get_state # get mp_state_thread ptr into eax + call MP_THREAD_GET_STATE # get mp_state_thread ptr into eax mov 4(%esp), %edx # load nlr_buf argument into edx (edx clobbered by call) mov NLR_TOP_TH_OFF(%eax), %ecx # get thread.nlr_top (last nlr_buf) mov %ecx, (%edx) # store it @@ -84,7 +96,7 @@ nlr_push: xor %eax, %eax # return 0, normal return ret # return -#if !defined(NLR_OS_WINDOWS) +#if !defined(NLR_OS_WINDOWS) && !defined(NLR_OS_MAC) .size nlr_push, .-nlr_push #endif @@ -95,6 +107,9 @@ nlr_push: .globl _nlr_pop .def _nlr_pop; .scl 2; .type 32; .endef _nlr_pop: +#elif defined(NLR_OS_MAC) + .globl _nlr_pop +_nlr_pop: #else .globl nlr_pop .type nlr_pop, @function @@ -106,14 +121,14 @@ nlr_pop: mov (%eax), %eax # load prev nlr_buf mov %eax, NLR_TOP # store nlr_top (to unlink list) #else - call mp_thread_get_state # get mp_state_thread ptr into eax + call MP_THREAD_GET_STATE # get mp_state_thread ptr into eax mov NLR_TOP_TH_OFF(%eax), %ecx # get thread.nlr_top (last nlr_buf) mov (%ecx), %ecx # load prev nlr_buf mov %ecx, NLR_TOP_TH_OFF(%eax) # store prev nlr_buf (to unlink list) #endif ret # return -#if !defined(NLR_OS_WINDOWS) +#if !defined(NLR_OS_WINDOWS) && !defined(NLR_OS_MAC) .size nlr_pop, .-nlr_pop #endif @@ -124,6 +139,9 @@ nlr_pop: .globl _nlr_jump .def _nlr_jump; .scl 2; .type 32; .endef _nlr_jump: +#elif defined(NLR_OS_MAC) + .globl _nlr_jump +_nlr_jump: #else .globl nlr_jump .type nlr_jump, @function @@ -133,7 +151,7 @@ nlr_jump: #if !MICROPY_PY_THREAD mov NLR_TOP, %edx # load nlr_top test %edx, %edx # check for nlr_top being NULL -#if defined(NLR_OS_WINDOWS) +#if defined(NLR_OS_WINDOWS) || defined(NLR_OS_MAC) je _nlr_jump_fail # fail if nlr_top is NULL #else je nlr_jump_fail # fail if nlr_top is NULL @@ -143,10 +161,10 @@ nlr_jump: mov (%edx), %eax # load prev nlr_top mov %eax, NLR_TOP # store nlr_top (to unlink list) #else - call mp_thread_get_state # get mp_state_thread ptr into eax + call MP_THREAD_GET_STATE # get mp_state_thread ptr into eax mov NLR_TOP_TH_OFF(%eax), %edx # get thread.nlr_top (last nlr_buf) test %edx, %edx # check for nlr_top being NULL -#if defined(NLR_OS_WINDOWS) +#if defined(NLR_OS_WINDOWS) || defined(NLR_OS_MAC) je _nlr_jump_fail # fail if nlr_top is NULL #else je nlr_jump_fail # fail if nlr_top is NULL @@ -167,7 +185,7 @@ nlr_jump: xor %eax, %eax # clear return register inc %al # increase to make 1, non-local return ret # return -#if !defined(NLR_OS_WINDOWS) +#if !defined(NLR_OS_WINDOWS) && !defined(NLR_OS_MAC) .size nlr_jump, .-nlr_jump #endif @@ -76,11 +76,7 @@ void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) { -#if MICROPY_PY_IO - mp_obj_print_helper(&mp_sys_stdout_print, o_in, kind); -#else - mp_obj_print_helper(&mp_plat_print, o_in, kind); -#endif + mp_obj_print_helper(MP_PYTHON_PRINTER, o_in, kind); } // helper function to print an exception with traceback @@ -270,29 +270,35 @@ static inline bool mp_obj_is_integer(mp_const_obj_t o) { return MP_OBJ_IS_INT(o) // These macros are used to declare and define constant function objects // You can put "static" in front of the definitions to make them local -#define MP_DECLARE_CONST_FUN_OBJ(obj_name) extern const mp_obj_fun_builtin_t obj_name +#define MP_DECLARE_CONST_FUN_OBJ_0(obj_name) extern const mp_obj_fun_builtin_fixed_t obj_name +#define MP_DECLARE_CONST_FUN_OBJ_1(obj_name) extern const mp_obj_fun_builtin_fixed_t obj_name +#define MP_DECLARE_CONST_FUN_OBJ_2(obj_name) extern const mp_obj_fun_builtin_fixed_t obj_name +#define MP_DECLARE_CONST_FUN_OBJ_3(obj_name) extern const mp_obj_fun_builtin_fixed_t obj_name +#define MP_DECLARE_CONST_FUN_OBJ_VAR(obj_name) extern const mp_obj_fun_builtin_var_t obj_name +#define MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name) extern const mp_obj_fun_builtin_var_t obj_name +#define MP_DECLARE_CONST_FUN_OBJ_KW(obj_name) extern const mp_obj_fun_builtin_var_t obj_name #define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) \ - const mp_obj_fun_builtin_t obj_name = \ - {{&mp_type_fun_builtin}, false, 0, 0, .fun._0 = fun_name} + const mp_obj_fun_builtin_fixed_t obj_name = \ + {{&mp_type_fun_builtin_0}, .fun._0 = fun_name} #define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) \ - const mp_obj_fun_builtin_t obj_name = \ - {{&mp_type_fun_builtin}, false, 1, 1, .fun._1 = fun_name} + const mp_obj_fun_builtin_fixed_t obj_name = \ + {{&mp_type_fun_builtin_1}, .fun._1 = fun_name} #define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) \ - const mp_obj_fun_builtin_t obj_name = \ - {{&mp_type_fun_builtin}, false, 2, 2, .fun._2 = fun_name} + const mp_obj_fun_builtin_fixed_t obj_name = \ + {{&mp_type_fun_builtin_2}, .fun._2 = fun_name} #define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) \ - const mp_obj_fun_builtin_t obj_name = \ - {{&mp_type_fun_builtin}, false, 3, 3, .fun._3 = fun_name} + const mp_obj_fun_builtin_fixed_t obj_name = \ + {{&mp_type_fun_builtin_3}, .fun._3 = fun_name} #define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) \ - const mp_obj_fun_builtin_t obj_name = \ - {{&mp_type_fun_builtin}, false, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.var = fun_name} + const mp_obj_fun_builtin_var_t obj_name = \ + {{&mp_type_fun_builtin_var}, false, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.var = fun_name} #define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) \ - const mp_obj_fun_builtin_t obj_name = \ - {{&mp_type_fun_builtin}, false, n_args_min, n_args_max, .fun.var = fun_name} + const mp_obj_fun_builtin_var_t obj_name = \ + {{&mp_type_fun_builtin_var}, false, n_args_min, n_args_max, .fun.var = fun_name} #define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \ - const mp_obj_fun_builtin_t obj_name = \ - {{&mp_type_fun_builtin}, true, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.kw = fun_name} + const mp_obj_fun_builtin_var_t obj_name = \ + {{&mp_type_fun_builtin_var}, true, n_args_min, MP_OBJ_FUN_ARGS_MAX, .fun.kw = fun_name} // These macros are used to define constant map/dict objects // You can put "static" in front of the definition to make it local @@ -530,7 +536,11 @@ extern const mp_obj_type_t mp_type_zip; extern const mp_obj_type_t mp_type_array; extern const mp_obj_type_t mp_type_super; extern const mp_obj_type_t mp_type_gen_instance; -extern const mp_obj_type_t mp_type_fun_builtin; +extern const mp_obj_type_t mp_type_fun_builtin_0; +extern const mp_obj_type_t mp_type_fun_builtin_1; +extern const mp_obj_type_t mp_type_fun_builtin_2; +extern const mp_obj_type_t mp_type_fun_builtin_3; +extern const mp_obj_type_t mp_type_fun_builtin_var; extern const mp_obj_type_t mp_type_fun_bc; extern const mp_obj_type_t mp_type_module; extern const mp_obj_type_t mp_type_staticmethod; @@ -740,27 +750,34 @@ void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item); void mp_obj_slice_get(mp_obj_t self_in, mp_obj_t *start, mp_obj_t *stop, mp_obj_t *step); // functions -#define MP_OBJ_FUN_ARGS_MAX (0xffff) // to set maximum value in n_args_max below -typedef struct _mp_obj_fun_builtin_t { // use this to make const objects that go in ROM + +typedef struct _mp_obj_fun_builtin_fixed_t { mp_obj_base_t base; - bool is_kw : 1; - mp_uint_t n_args_min : 15; // inclusive - mp_uint_t n_args_max : 16; // inclusive union { mp_fun_0_t _0; mp_fun_1_t _1; mp_fun_2_t _2; mp_fun_3_t _3; + } fun; +} mp_obj_fun_builtin_fixed_t; + +#define MP_OBJ_FUN_ARGS_MAX (0xffff) // to set maximum value in n_args_max below +typedef struct _mp_obj_fun_builtin_var_t { + mp_obj_base_t base; + bool is_kw : 1; + mp_uint_t n_args_min : 15; // inclusive + mp_uint_t n_args_max : 16; // inclusive + union { mp_fun_var_t var; mp_fun_kw_t kw; } fun; -} mp_obj_fun_builtin_t; +} mp_obj_fun_builtin_var_t; qstr mp_obj_fun_get_name(mp_const_obj_t fun); qstr mp_obj_code_get_name(const byte *code_info); mp_obj_t mp_identity(mp_obj_t self); -MP_DECLARE_CONST_FUN_OBJ(mp_identity_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj); // module typedef struct _mp_obj_module_t { diff --git a/py/objfun.c b/py/objfun.c index 405f38127a..6b8fe6d382 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -50,11 +50,66 @@ /******************************************************************************/ /* builtin functions */ -// mp_obj_fun_builtin_t defined in obj.h +STATIC mp_obj_t fun_builtin_0_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + (void)args; + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_0)); + mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); + mp_arg_check_num(n_args, n_kw, 0, 0, false); + return self->fun._0(); +} -STATIC mp_obj_t fun_builtin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin)); - mp_obj_fun_builtin_t *self = MP_OBJ_TO_PTR(self_in); +const mp_obj_type_t mp_type_fun_builtin_0 = { + { &mp_type_type }, + .name = MP_QSTR_function, + .call = fun_builtin_0_call, + .unary_op = mp_generic_unary_op, +}; + +STATIC mp_obj_t fun_builtin_1_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_1)); + mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); + mp_arg_check_num(n_args, n_kw, 1, 1, false); + return self->fun._1(args[0]); +} + +const mp_obj_type_t mp_type_fun_builtin_1 = { + { &mp_type_type }, + .name = MP_QSTR_function, + .call = fun_builtin_1_call, + .unary_op = mp_generic_unary_op, +}; + +STATIC mp_obj_t fun_builtin_2_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_2)); + mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); + mp_arg_check_num(n_args, n_kw, 2, 2, false); + return self->fun._2(args[0], args[1]); +} + +const mp_obj_type_t mp_type_fun_builtin_2 = { + { &mp_type_type }, + .name = MP_QSTR_function, + .call = fun_builtin_2_call, + .unary_op = mp_generic_unary_op, +}; + +STATIC mp_obj_t fun_builtin_3_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_3)); + mp_obj_fun_builtin_fixed_t *self = MP_OBJ_TO_PTR(self_in); + mp_arg_check_num(n_args, n_kw, 3, 3, false); + return self->fun._3(args[0], args[1], args[2]); +} + +const mp_obj_type_t mp_type_fun_builtin_3 = { + { &mp_type_type }, + .name = MP_QSTR_function, + .call = fun_builtin_3_call, + .unary_op = mp_generic_unary_op, +}; + +STATIC mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_fun_builtin_var)); + mp_obj_fun_builtin_var_t *self = MP_OBJ_TO_PTR(self_in); // check number of arguments mp_arg_check_num(n_args, n_kw, self->n_args_min, self->n_args_max, self->is_kw); @@ -68,25 +123,6 @@ STATIC mp_obj_t fun_builtin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c return self->fun.kw(n_args, args, &kw_args); - } else if (self->n_args_min <= 3 && self->n_args_min == self->n_args_max) { - // function requires a fixed number of arguments - - // dispatch function call - switch (self->n_args_min) { - case 0: - return self->fun._0(); - - case 1: - return self->fun._1(args[0]); - - case 2: - return self->fun._2(args[0], args[1]); - - case 3: - default: - return self->fun._3(args[0], args[1], args[2]); - } - } else { // function takes a variable number of arguments, but no keywords @@ -94,10 +130,10 @@ STATIC mp_obj_t fun_builtin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c } } -const mp_obj_type_t mp_type_fun_builtin = { +const mp_obj_type_t mp_type_fun_builtin_var = { { &mp_type_type }, .name = MP_QSTR_function, - .call = fun_builtin_call, + .call = fun_builtin_var_call, .unary_op = mp_generic_unary_op, }; diff --git a/py/objstr.h b/py/objstr.h index e14568dac4..ad2777afbc 100644 --- a/py/objstr.h +++ b/py/objstr.h @@ -74,32 +74,32 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s mp_obj_t index, bool is_slice); const byte *find_subbytes(const byte *haystack, mp_uint_t hlen, const byte *needle, mp_uint_t nlen, mp_int_t direction); -MP_DECLARE_CONST_FUN_OBJ(str_encode_obj); -MP_DECLARE_CONST_FUN_OBJ(str_find_obj); -MP_DECLARE_CONST_FUN_OBJ(str_rfind_obj); -MP_DECLARE_CONST_FUN_OBJ(str_index_obj); -MP_DECLARE_CONST_FUN_OBJ(str_rindex_obj); -MP_DECLARE_CONST_FUN_OBJ(str_join_obj); -MP_DECLARE_CONST_FUN_OBJ(str_split_obj); -MP_DECLARE_CONST_FUN_OBJ(str_splitlines_obj); -MP_DECLARE_CONST_FUN_OBJ(str_rsplit_obj); -MP_DECLARE_CONST_FUN_OBJ(str_startswith_obj); -MP_DECLARE_CONST_FUN_OBJ(str_endswith_obj); -MP_DECLARE_CONST_FUN_OBJ(str_strip_obj); -MP_DECLARE_CONST_FUN_OBJ(str_lstrip_obj); -MP_DECLARE_CONST_FUN_OBJ(str_rstrip_obj); -MP_DECLARE_CONST_FUN_OBJ(str_format_obj); -MP_DECLARE_CONST_FUN_OBJ(str_replace_obj); -MP_DECLARE_CONST_FUN_OBJ(str_count_obj); -MP_DECLARE_CONST_FUN_OBJ(str_partition_obj); -MP_DECLARE_CONST_FUN_OBJ(str_rpartition_obj); -MP_DECLARE_CONST_FUN_OBJ(str_center_obj); -MP_DECLARE_CONST_FUN_OBJ(str_lower_obj); -MP_DECLARE_CONST_FUN_OBJ(str_upper_obj); -MP_DECLARE_CONST_FUN_OBJ(str_isspace_obj); -MP_DECLARE_CONST_FUN_OBJ(str_isalpha_obj); -MP_DECLARE_CONST_FUN_OBJ(str_isdigit_obj); -MP_DECLARE_CONST_FUN_OBJ(str_isupper_obj); -MP_DECLARE_CONST_FUN_OBJ(str_islower_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_index_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj); +MP_DECLARE_CONST_FUN_OBJ_2(str_join_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_split_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(str_splitlines_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rsplit_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_strip_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_lstrip_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rstrip_obj); +MP_DECLARE_CONST_FUN_OBJ_KW(str_format_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_replace_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_count_obj); +MP_DECLARE_CONST_FUN_OBJ_2(str_partition_obj); +MP_DECLARE_CONST_FUN_OBJ_2(str_rpartition_obj); +MP_DECLARE_CONST_FUN_OBJ_2(str_center_obj); +MP_DECLARE_CONST_FUN_OBJ_1(str_lower_obj); +MP_DECLARE_CONST_FUN_OBJ_1(str_upper_obj); +MP_DECLARE_CONST_FUN_OBJ_1(str_isspace_obj); +MP_DECLARE_CONST_FUN_OBJ_1(str_isalpha_obj); +MP_DECLARE_CONST_FUN_OBJ_1(str_isdigit_obj); +MP_DECLARE_CONST_FUN_OBJ_1(str_isupper_obj); +MP_DECLARE_CONST_FUN_OBJ_1(str_islower_obj); #endif // __MICROPY_INCLUDED_PY_OBJSTR_H__ diff --git a/py/parse.c b/py/parse.c index 5920828fe9..397d46d9f0 100644 --- a/py/parse.c +++ b/py/parse.c @@ -1010,9 +1010,10 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { // truncate final chunk and link into chain of chunks if (parser.cur_chunk != NULL) { - (void)m_renew(byte, parser.cur_chunk, + (void)m_renew_maybe(byte, parser.cur_chunk, sizeof(mp_parse_chunk_t) + parser.cur_chunk->alloc, - sizeof(mp_parse_chunk_t) + parser.cur_chunk->union_.used); + sizeof(mp_parse_chunk_t) + parser.cur_chunk->union_.used, + false); parser.cur_chunk->alloc = parser.cur_chunk->union_.used; parser.cur_chunk->union_.next = parser.tree.chunk; parser.tree.chunk = parser.cur_chunk; diff --git a/py/parsenum.c b/py/parsenum.c index 1010ad3055..b1c449c9b8 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -227,7 +227,7 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool } else { if (in == PARSE_DEC_IN_FRAC) { dec_val += dig * frac_mult; - frac_mult *= 0.1; + frac_mult *= MICROPY_FLOAT_CONST(0.1); } else { dec_val = 10 * dec_val + dig; } @@ -230,13 +230,23 @@ PY_O_BASENAME = \ ../extmod/vfs_fat_lexer.o \ ../extmod/vfs_fat_misc.o \ ../extmod/utime_mphal.o \ - ../extmod/moduos_dupterm.o \ + ../extmod/uos_dupterm.o \ ../lib/embed/abort_.o \ ../lib/utils/printf.o \ # prepend the build destination prefix to the py object files PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME)) +# object file for frozen files +ifneq ($(FROZEN_DIR),) +PY_O += $(BUILD)/$(BUILD)/frozen.o +endif + +# object file for frozen bytecode (frozen .mpy files) +ifneq ($(FROZEN_MPY_DIR),) +PY_O += $(BUILD)/$(BUILD)/frozen_mpy.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) @@ -199,7 +199,7 @@ qstr qstr_from_strn(const char *str, size_t len) { byte *new_p = m_renew_maybe(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_alloc) + n_bytes, false); if (new_p == NULL) { // could not grow existing memory; shrink it to fit previous - (void)m_renew(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_used)); + (void)m_renew_maybe(byte, MP_STATE_VM(qstr_last_chunk), MP_STATE_VM(qstr_last_alloc), MP_STATE_VM(qstr_last_used), false); MP_STATE_VM(qstr_last_chunk) = NULL; } else { // could grow existing memory diff --git a/py/runtime.c b/py/runtime.c index 6eda77ee9c..c255574643 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -972,7 +972,13 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t || ((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type->name == MP_QSTR_generator))) { // only functions, closures and generators objects can be bound to self #if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG - if (self == MP_OBJ_NULL && mp_obj_get_type(member) == &mp_type_fun_builtin) { + const mp_obj_type_t *m_type = ((mp_obj_base_t*)MP_OBJ_TO_PTR(member))->type; + if (self == MP_OBJ_NULL + && (m_type == &mp_type_fun_builtin_0 + || m_type == &mp_type_fun_builtin_1 + || m_type == &mp_type_fun_builtin_2 + || m_type == &mp_type_fun_builtin_3 + || m_type == &mp_type_fun_builtin_var)) { // we extracted a builtin method without a first argument, so we must // wrap this function in a type checker dest[0] = mp_obj_new_checked_fun(type, member); diff --git a/py/sequence.c b/py/sequence.c index 0acdd25be0..bc2cfc077c 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -53,15 +53,35 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice mp_int_t start, stop; mp_obj_slice_get(slice, &ostart, &ostop, &ostep); + if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) { + indexes->step = mp_obj_get_int(ostep); + if (indexes->step == 0) { + mp_raise_ValueError("slice step cannot be zero"); + } + } else { + indexes->step = 1; + } + if (ostart == mp_const_none) { - start = 0; + if (indexes->step > 0) { + start = 0; + } else { + start = len - 1; + } } else { start = mp_obj_get_int(ostart); } if (ostop == mp_const_none) { - stop = len; + if (indexes->step > 0) { + stop = len; + } else { + stop = 0; + } } else { stop = mp_obj_get_int(ostop); + if (stop >= 0 && indexes->step < 0) { + stop += 1; + } } // Unlike subscription, out-of-bounds slice indexes are never error @@ -70,29 +90,31 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice if (start < 0) { start = 0; } - } else if ((mp_uint_t)start > len) { + } else if (indexes->step > 0 && (mp_uint_t)start > len) { start = len; + } else if (indexes->step < 0 && (mp_uint_t)start > len - 1) { + start = len - 1; } if (stop < 0) { stop = len + stop; + if (indexes->step < 0) { + stop += 1; + } } else if ((mp_uint_t)stop > len) { stop = len; } // CPython returns empty sequence in such case, or point for assignment is at start - if (start > stop) { + if (indexes->step > 0 && start > stop) { stop = start; + } else if (indexes->step < 0 && start < stop) { + stop = start + 1; } indexes->start = start; indexes->stop = stop; - if (ostep != mp_const_none && ostep != MP_OBJ_NEW_SMALL_INT(1)) { - indexes->step = mp_obj_get_int(ostep); - return false; - } - indexes->step = 1; - return true; + return indexes->step == 1; } #endif @@ -106,10 +128,9 @@ mp_obj_t mp_seq_extract_slice(mp_uint_t len, const mp_obj_t *seq, mp_bound_slice mp_obj_t res = mp_obj_new_list(0, NULL); if (step < 0) { - stop--; - while (start <= stop) { - mp_obj_list_append(res, seq[stop]); - stop += step; + while (start >= stop) { + mp_obj_list_append(res, seq[start]); + start += step; } } else { while (start < stop) { diff --git a/py/stream.c b/py/stream.c index cc8a63ac2e..dadfcf5d62 100644 --- a/py/stream.c +++ b/py/stream.c @@ -391,7 +391,7 @@ STATIC mp_obj_t stream_unbuffered_readline(size_t n_args, const mp_obj_t *args) if (mp_is_nonblocking_error(error)) { if (vstr.len == 1) { // We just incremented it, but otherwise we read nothing - // and immediately got EAGAIN. This is case is not well + // and immediately got EAGAIN. This case is not well // specified in // https://docs.python.org/3/library/io.html#io.IOBase.readline // unlike similar case for read(). But we follow the latter's diff --git a/py/stream.h b/py/stream.h index 33d85e823c..4cdea11eba 100644 --- a/py/stream.h +++ b/py/stream.h @@ -48,18 +48,18 @@ struct mp_stream_seek_t { int whence; }; -MP_DECLARE_CONST_FUN_OBJ(mp_stream_read_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_read1_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_readinto_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_readall_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_unbuffered_readline_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_unbuffered_readlines_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_write_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_write1_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_seek_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_tell_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_flush_obj); -MP_DECLARE_CONST_FUN_OBJ(mp_stream_ioctl_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read1_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_readinto_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_stream_readall_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_stream_unbuffered_readlines_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_write_obj); +MP_DECLARE_CONST_FUN_OBJ_2(mp_stream_write1_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_seek_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_stream_tell_obj); +MP_DECLARE_CONST_FUN_OBJ_1(mp_stream_flush_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj); // these are for mp_get_stream_raise and can be or'd together #define MP_STREAM_OP_READ (1) diff --git a/py/warning.c b/py/warning.c index eae145bd3f..4cdf3b3f10 100644 --- a/py/warning.c +++ b/py/warning.c @@ -38,6 +38,7 @@ void mp_warning(const char *msg, ...) { mp_print_str(&mp_plat_print, "Warning: "); mp_vprintf(&mp_plat_print, msg, args); mp_print_str(&mp_plat_print, "\n"); + va_end(args); } void mp_emitter_warning(pass_kind_t pass, const char *msg) { |