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) {
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: