diff --git a/py/builtin.h b/py/builtin.h index a5e0f5f2d0fbb..863956e2b9a38 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -75,7 +75,8 @@ 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); +//MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj); +extern const struct _mp_obj_fun_bc_t mp_builtin_sum_obj; // Defined by a port, but declared here for simplicity MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj); MP_DECLARE_CONST_FUN_OBJ_KW(mp_builtin_open_obj); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index a65f3beecfa8b..67e8605a3e870 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -521,6 +521,106 @@ STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_round_obj, 1, 2, mp_builtin_round); +#if 1 + +// Implement sum() in Python! +// +// def sum(iterable, start=0): +// for x in iterable: +// start += x +// return start + +#include "py/bc0.h" +#include "py/runtime0.h" +#include "py/objfun.h" + +extern const mp_obj_type_t mp_type_fun_native; + +#if 1 +// Implement sum in Python bytecode + +STATIC const uint8_t mp_builtin_sum_bytecode[] = { + 0x09, // n_state + 0x00, // n_exc_stack + 0x80, // scope_flags (special top-bit set for internal bytecode function) + 0x02, // n_pos_args + 0x00, // n_kwonly_args + 0x01, // n_def_pos_args + 0x03, // code_info_size + MP_QSTR_sum & 0xff, MP_QSTR_sum >> 8, // simple_name + 0xff, // end-of-list-sentinel for cells + + MP_BC_LOAD_FAST_MULTI, + MP_BC_GET_ITER_STACK, + MP_BC_FOR_ITER, 0x08, 0x00, // +8 + MP_BC_STORE_FAST_MULTI + 2, + MP_BC_LOAD_FAST_MULTI + 1, + MP_BC_LOAD_FAST_MULTI + 2, + MP_BC_BINARY_OP_MULTI + MP_BINARY_OP_INPLACE_ADD, + MP_BC_STORE_FAST_MULTI + 1, + MP_BC_JUMP, 0xf5, 0x7f, // -11 + MP_BC_LOAD_FAST_MULTI + 1, + MP_BC_RETURN_VALUE, +}; +const mp_obj_fun_bc_t mp_builtin_sum_obj = { + .base = { &mp_type_fun_bc }, + .globals = NULL, + .bytecode = mp_builtin_sum_bytecode, + .const_table = NULL, + { MP_OBJ_NEW_SMALL_INT(0) }, // default start value +}; + +#else +// Implement sum in Python native code + +#if defined(__x86_64__) +STATIC const byte mp_builtin_sum_fun_data[159] __attribute__((section(".text,\"ax\",@progbits # "))) = { + 0x55, 0x53, 0x41, 0x54, 0x41, 0x55, 0x48, 0x83, 0xec, 0x78, 0x4c, 0x8b, 0x6f, 0x18, 0x49, 0x8b, + 0x6d, 0x10, 0x48, 0x89, 0x3c, 0x24, 0xbf, 0x92, 0x00, 0x00, 0x00, 0x48, 0x89, 0x7c, 0x24, 0x08, + 0x48, 0x89, 0xe7, 0x48, 0x8b, 0x85, 0x70, 0x01, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x8b, 0x5c, 0x24, + 0x68, 0x4c, 0x8b, 0x64, 0x24, 0x60, 0x4c, 0x8b, 0x6c, 0x24, 0x58, 0x48, 0x89, 0xdf, 0x48, 0x8d, + 0x74, 0x24, 0x28, 0x48, 0x8b, 0x85, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x8d, 0x7c, 0x24, + 0x28, 0x48, 0x8b, 0x85, 0xf8, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x48, 0x85, 0xc0, 0x0f, 0x84, 0x1c, + 0x00, 0x00, 0x00, 0x49, 0x89, 0xc5, 0x4c, 0x89, 0xea, 0x4c, 0x89, 0xe6, 0xbf, 0x0e, 0x00, 0x00, + 0x00, 0x48, 0x8b, 0x85, 0x90, 0x00, 0x00, 0x00, 0xff, 0xd0, 0x49, 0x89, 0xc4, 0xeb, 0xcd, 0x4c, + 0x89, 0xe0, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0xec, 0x88, 0x41, 0x5d, 0x41, 0x5c, 0x5b, + 0x5d, 0xc3, + 0x80, 0x09, 0x00, 0x00, 0x02, 0x00, 0x01, 0x05, + MP_QSTR_sum & 0xff, MP_QSTR_sum >> 8, + MP_QSTR_sum_dot_py & 0xff, MP_QSTR_sum_dot_py >> 8, + 0xff, +}; +#elif defined(__thumb2__) +STATIC const byte mp_builtin_sum_fun_data[87] __attribute__((section(".text,\"ax\",%progbits @ "))) __attribute__ ((aligned (2))) = { + 0xfe, 0xb5, 0x8c, 0xb0, 0xc6, 0x68, 0xb7, 0x68, 0x00, 0x90, 0x4a, 0x20, 0x01, 0x90, 0x00, 0xa8, + 0xd7, 0xf8, 0xb8, 0x40, 0xa0, 0x47, 0x0d, 0x9c, 0x0c, 0x9d, 0x0b, 0x9e, 0x20, 0x46, 0x05, 0xa9, + 0xbb, 0x6f, 0x98, 0x47, 0x05, 0xa8, 0xfb, 0x6f, 0x98, 0x47, 0x00, 0x28, 0x00, 0xf0, 0x08, 0x80, + 0x06, 0x46, 0x32, 0x46, 0x29, 0x46, 0x0e, 0x20, 0xbb, 0x6c, 0x98, 0x47, 0x05, 0x46, 0xf1, 0xe7, + 0x28, 0x46, 0x00, 0xf0, 0x00, 0xb8, 0x0c, 0xb0, 0xfe, 0xbd, + 0x80, 0x09, 0x00, 0x00, 0x02, 0x00, 0x01, 0x05, + MP_QSTR_sum & 0xff, MP_QSTR_sum >> 8, + MP_QSTR_sum_dot_py & 0xff, MP_QSTR_sum_dot_py >> 8, + 0xff, +}; +#endif +STATIC const mp_rom_obj_t mp_builtin_sum_const_table[3] = { + MP_ROM_QSTR(MP_QSTR_iterable), + MP_ROM_QSTR(MP_QSTR_start), + mp_fun_table, +}; +const mp_obj_fun_bc_t mp_builtin_sum_obj = { + .base = { &mp_type_fun_native }, + .globals = NULL, + .bytecode = mp_builtin_sum_fun_data, + .const_table = (void*)mp_builtin_sum_const_table, + { MP_OBJ_NEW_SMALL_INT(0) }, // default start value +}; + +#endif + +#else +// Implement sum in C + STATIC mp_obj_t mp_builtin_sum(size_t n_args, const mp_obj_t *args) { mp_obj_t value; switch (n_args) { @@ -537,6 +637,8 @@ STATIC mp_obj_t mp_builtin_sum(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_sum_obj, 1, 2, mp_builtin_sum); +#endif + STATIC mp_obj_t mp_builtin_sorted(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) { if (n_args > 1) { mp_raise_TypeError("must use keyword argument for key function"); diff --git a/py/objfun.c b/py/objfun.c index e0c6fb9271276..0df33fb63463f 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -148,7 +148,7 @@ qstr mp_obj_code_get_name(const byte *code_info) { } #if MICROPY_EMIT_NATIVE -STATIC const mp_obj_type_t mp_type_fun_native; +const mp_obj_type_t mp_type_fun_native; #endif qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) { @@ -406,7 +406,7 @@ STATIC mp_obj_t fun_native_call(mp_obj_t self_in, size_t n_args, size_t n_kw, co return fun(self_in, n_args, n_kw, args); } -STATIC const mp_obj_type_t mp_type_fun_native = { +const mp_obj_type_t mp_type_fun_native = { { &mp_type_type }, .name = MP_QSTR_function, .call = fun_native_call, diff --git a/py/vm.c b/py/vm.c index 260a7f38baf9d..4c861e014499f 100644 --- a/py/vm.c +++ b/py/vm.c @@ -1365,6 +1365,10 @@ unwind_jump:; const byte *ip = code_state->fun_bc->bytecode; ip = mp_decode_uint_skip(ip); // skip n_state ip = mp_decode_uint_skip(ip); // skip n_exc_stack + if (*ip & 0x80) { + // builtin bytecode, don't add traceback info + goto skip_traceback; + } ip++; // skip scope_params ip++; // skip n_pos_args ip++; // skip n_kwonly_args @@ -1407,6 +1411,7 @@ unwind_jump:; } } mp_obj_exception_add_traceback(MP_OBJ_FROM_PTR(nlr.ret_val), source_file, source_line, block_name); + skip_traceback:; } while (exc_sp >= exc_stack && exc_sp->handler <= code_state->ip) {