diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/builtin.c | 2 | ||||
-rw-r--r-- | py/compile.c | 54 | ||||
-rw-r--r-- | py/emitbc.c | 27 | ||||
-rw-r--r-- | py/emitglue.c | 9 | ||||
-rw-r--r-- | py/emitnative.c | 16 | ||||
-rw-r--r-- | py/objdict.c | 2 | ||||
-rw-r--r-- | py/objfun.c | 6 | ||||
-rw-r--r-- | py/objgenerator.c | 12 | ||||
-rw-r--r-- | py/objstr.c | 4 | ||||
-rw-r--r-- | py/objtype.c | 4 | ||||
-rw-r--r-- | py/runtime.c | 70 | ||||
-rw-r--r-- | py/runtime.h | 13 | ||||
-rw-r--r-- | py/vm.c | 35 | ||||
-rw-r--r-- | py/vstr.c | 4 |
14 files changed, 138 insertions, 120 deletions
diff --git a/py/builtin.c b/py/builtin.c index d606db17f4..57d3aa70b7 100644 --- a/py/builtin.c +++ b/py/builtin.c @@ -192,7 +192,7 @@ STATIC mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) { mp_obj_t args[2]; args[0] = MP_OBJ_NEW_SMALL_INT(i1 / i2); args[1] = MP_OBJ_NEW_SMALL_INT(i1 % i2); - return mp_build_tuple(2, args); + return mp_obj_new_tuple(2, args); } else { nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in))); } diff --git a/py/compile.c b/py/compile.c index dc5a8b38a2..25830eb6f9 100644 --- a/py/compile.c +++ b/py/compile.c @@ -776,17 +776,14 @@ void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_kind) { } // stuff for lambda and comprehensions and generators +// if we are not in CPython compatibility mode then: +// if n_pos_defaults > 0 then there is a tuple on the stack with the positional defaults +// if n_kw_defaults > 0 then there is a dictionary on the stack with the keyword defaults +// if both exist, the tuple is above the dictionary (ie the first pop gets the tuple) void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_pos_defaults, int n_kw_defaults) { assert(n_pos_defaults >= 0); assert(n_kw_defaults >= 0); -#if !MICROPY_EMIT_CPYTHON - // in Micro Python we put the default params into a tuple using the bytecode - if (n_pos_defaults) { - EMIT_ARG(build_tuple, n_pos_defaults); - } -#endif - // make closed over variables, if any // ensure they are closed over in the order defined in the outer scope (mainly to agree with CPython) int nfree = 0; @@ -870,8 +867,19 @@ void compile_funcdef_param(compiler_t *comp, mp_parse_node_t pn) { if (comp->have_bare_star) { comp->param_pass_num_dict_params += 1; if (comp->param_pass == 1) { +#if !MICROPY_EMIT_CPYTHON + // in Micro Python we put the default dict parameters into a dictionary using the bytecode + if (comp->param_pass_num_dict_params == 1) { + // first default dict param, so make the map + EMIT_ARG(build_map, 0); + } +#endif EMIT_ARG(load_const_id, MP_PARSE_NODE_LEAF_ARG(pn_id)); compile_node(comp, pn_equal); +#if !MICROPY_EMIT_CPYTHON + // in Micro Python we put the default dict parameters into a dictionary using the bytecode + EMIT(store_map); +#endif } } else { comp->param_pass_num_default_params += 1; @@ -922,6 +930,13 @@ qstr compile_funcdef_helper(compiler_t *comp, mp_parse_node_struct_t *pns, uint comp->param_pass_num_default_params = 0; apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_funcdef_param); +#if !MICROPY_EMIT_CPYTHON + // in Micro Python we put the default positional parameters into a tuple using the bytecode + if (comp->param_pass_num_default_params > 0) { + EMIT_ARG(build_tuple, comp->param_pass_num_default_params); + } +#endif + // get the scope for this function scope_t *fscope = (scope_t*)pns->nodes[4]; @@ -1519,35 +1534,41 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { } // TODO preload end and step onto stack if they are not constants -// TODO check if step is negative and do opposite test +// Note that, as per semantics of for .. range, the final failing value should not be stored in the loop variable +// And, if the loop never runs, the loop variable should never be assigned void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var, mp_parse_node_t pn_start, mp_parse_node_t pn_end, mp_parse_node_t pn_step, mp_parse_node_t pn_body, mp_parse_node_t pn_else) { START_BREAK_CONTINUE_BLOCK int top_label = comp_next_label(comp); int entry_label = comp_next_label(comp); - // compile: var = start + // compile: start, duplicated on stack compile_node(comp, pn_start); - c_assign(comp, pn_var, ASSIGN_STORE); + EMIT(dup_top); EMIT_ARG(jump, entry_label); EMIT_ARG(label_assign, top_label); + // at this point we actually have 1 less element on the stack + EMIT_ARG(set_stack_size, EMIT(get_stack_size) - 1); + + // store next value to var + c_assign(comp, pn_var, ASSIGN_STORE); + // compile body compile_node(comp, pn_body); EMIT_ARG(label_assign, continue_label); - // compile: var += step - c_assign(comp, pn_var, ASSIGN_AUG_LOAD); + // compile: var + step, duplicated on stack + compile_node(comp, pn_var); compile_node(comp, pn_step); EMIT_ARG(binary_op, MP_BINARY_OP_INPLACE_ADD); - c_assign(comp, pn_var, ASSIGN_AUG_STORE); + EMIT(dup_top); EMIT_ARG(label_assign, entry_label); // compile: if var <cond> end: goto top - compile_node(comp, pn_var); compile_node(comp, pn_end); assert(MP_PARSE_NODE_IS_SMALL_INT(pn_step)); if (MP_PARSE_NODE_LEAF_SMALL_INT(pn_step) >= 0) { @@ -1557,6 +1578,9 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var, } EMIT_ARG(pop_jump_if_true, top_label); + // discard final value of var that failed the loop condition + EMIT(pop_top); + // break/continue apply to outer loop (if any) in the else block END_BREAK_CONTINUE_BLOCK @@ -3327,7 +3351,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) { #else // return function that executes the outer module // we can free the unique_code slot because no-one has reference to this unique_code_id anymore - return mp_make_function_from_id(unique_code_id, true, MP_OBJ_NULL); + return mp_make_function_from_id(unique_code_id, true, MP_OBJ_NULL, MP_OBJ_NULL); #endif } } diff --git a/py/emitbc.c b/py/emitbc.c index 595c7ac196..0a83448559 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -732,23 +732,38 @@ STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) { } STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) { - assert(n_kw_defaults == 0); - if (n_pos_defaults == 0) { + if (n_pos_defaults == 0 && n_kw_defaults == 0) { emit_bc_pre(emit, 1); emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id); } else { - emit_bc_pre(emit, 0); + if (n_pos_defaults == 0) { + // load dummy entry for non-existent positional default tuple + emit_bc_load_null(emit); + } else if (n_kw_defaults == 0) { + // load dummy entry for non-existent keyword default dict + emit_bc_load_null(emit); + emit_bc_rot_two(emit); + } + emit_bc_pre(emit, -1); emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id); } } STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) { - assert(n_kw_defaults == 0); - if (n_pos_defaults == 0) { + if (n_pos_defaults == 0 && n_kw_defaults == 0) { emit_bc_pre(emit, 0); emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id); } else { - emit_bc_pre(emit, -1); + if (n_pos_defaults == 0) { + // load dummy entry for non-existent positional default tuple + emit_bc_load_null(emit); + emit_bc_rot_two(emit); + } else if (n_kw_defaults == 0) { + // load dummy entry for non-existent keyword default dict + emit_bc_load_null(emit); + emit_bc_rot_three(emit); + } + emit_bc_pre(emit, -2); emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id); } } diff --git a/py/emitglue.c b/py/emitglue.c index 73304de27a..dc084e159c 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -190,13 +190,16 @@ void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint le #endif } -mp_obj_t mp_make_function_from_id(uint unique_code_id, bool free_unique_code, mp_obj_t def_args) { +mp_obj_t mp_make_function_from_id(uint unique_code_id, bool free_unique_code, mp_obj_t def_args, mp_obj_t def_kw_args) { DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id); if (unique_code_id >= unique_codes_total) { // illegal code id return mp_const_none; } + // TODO implement default kw args + assert(def_kw_args == MP_OBJ_NULL); + // make the function, depending on the code kind mp_code_t *c = &unique_codes[unique_code_id]; mp_obj_t fun; @@ -231,10 +234,10 @@ mp_obj_t mp_make_function_from_id(uint unique_code_id, bool free_unique_code, mp return fun; } -mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args) { +mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args) { DEBUG_OP_printf("make_closure_from_id %d\n", unique_code_id); // make function object - mp_obj_t ffun = mp_make_function_from_id(unique_code_id, false, def_args); + mp_obj_t ffun = mp_make_function_from_id(unique_code_id, false, def_args, def_kw_args); // wrap function in closure object return mp_obj_new_closure(ffun, closure_tuple); } diff --git a/py/emitnative.c b/py/emitnative.c index 73851120ad..da0aa60381 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -1063,14 +1063,14 @@ STATIC void emit_native_build_tuple(emit_t *emit, int n_args) { // if wrapped in byte_array, or something, allocates memory and fills it emit_native_pre(emit); emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items - emit_call_with_imm_arg(emit, MP_F_BUILD_TUPLE, mp_build_tuple, n_args, REG_ARG_1); + emit_call_with_imm_arg(emit, MP_F_BUILD_TUPLE, mp_obj_new_tuple, n_args, REG_ARG_1); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new tuple } STATIC void emit_native_build_list(emit_t *emit, int n_args) { emit_native_pre(emit); emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items - emit_call_with_imm_arg(emit, MP_F_BUILD_LIST, mp_build_list, n_args, REG_ARG_1); + emit_call_with_imm_arg(emit, MP_F_BUILD_LIST, mp_obj_new_list, n_args, REG_ARG_1); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new list } @@ -1081,13 +1081,13 @@ STATIC void emit_native_list_append(emit_t *emit, int list_index) { emit_access_stack(emit, list_index, &vtype_list, REG_ARG_1); assert(vtype_list == VTYPE_PYOBJ); assert(vtype_item == VTYPE_PYOBJ); - emit_call(emit, MP_F_LIST_APPEND, mp_list_append); + emit_call(emit, MP_F_LIST_APPEND, mp_obj_list_append); emit_post(emit); } STATIC void emit_native_build_map(emit_t *emit, int n_args) { emit_native_pre(emit); - emit_call_with_imm_arg(emit, MP_F_BUILD_MAP, mp_build_map, n_args, REG_ARG_1); + emit_call_with_imm_arg(emit, MP_F_BUILD_MAP, mp_obj_new_dict, n_args, REG_ARG_1); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new map } @@ -1097,7 +1097,7 @@ STATIC void emit_native_store_map(emit_t *emit) { assert(vtype_key == VTYPE_PYOBJ); assert(vtype_value == VTYPE_PYOBJ); assert(vtype_map == VTYPE_PYOBJ); - emit_call(emit, MP_F_STORE_MAP, mp_store_map); + emit_call(emit, MP_F_STORE_MAP, mp_obj_dict_store); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // map } @@ -1109,14 +1109,14 @@ STATIC void emit_native_map_add(emit_t *emit, int map_index) { assert(vtype_map == VTYPE_PYOBJ); assert(vtype_key == VTYPE_PYOBJ); assert(vtype_value == VTYPE_PYOBJ); - emit_call(emit, MP_F_STORE_MAP, mp_store_map); + emit_call(emit, MP_F_STORE_MAP, mp_obj_dict_store); emit_post(emit); } STATIC void emit_native_build_set(emit_t *emit, int n_args) { emit_native_pre(emit); emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, n_args); // pointer to items - emit_call_with_imm_arg(emit, MP_F_BUILD_SET, mp_build_set, n_args, REG_ARG_1); + emit_call_with_imm_arg(emit, MP_F_BUILD_SET, mp_obj_new_set, n_args, REG_ARG_1); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); // new set } @@ -1127,7 +1127,7 @@ STATIC void emit_native_set_add(emit_t *emit, int set_index) { emit_access_stack(emit, set_index, &vtype_set, REG_ARG_1); assert(vtype_set == VTYPE_PYOBJ); assert(vtype_item == VTYPE_PYOBJ); - emit_call(emit, MP_F_STORE_SET, mp_store_set); + emit_call(emit, MP_F_STORE_SET, mp_obj_set_store); emit_post(emit); } diff --git a/py/objdict.c b/py/objdict.c index 01c7294a46..afd1d0da0f 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -33,7 +33,7 @@ STATIC void dict_print(void (*print)(void *env, const char *fmt, ...), void *env STATIC mp_obj_t dict_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO create from an iterable! - return mp_build_map(0); + return mp_obj_new_dict(0); } STATIC mp_obj_t dict_unary_op(int op, mp_obj_t self_in) { diff --git a/py/objfun.c b/py/objfun.c index 154630afb6..3b48b570fd 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -151,15 +151,17 @@ typedef struct _mp_obj_fun_bc_t { mp_obj_t extra_args[]; // values of default args (if any), plus a slot at the end for var args and/or kw args (if it takes them) } mp_obj_fun_bc_t; -void dump_args(const mp_obj_t *a, int sz) { #if DEBUG_PRINT +STATIC void dump_args(const mp_obj_t *a, int sz) { DEBUG_printf("%p: ", a); for (int i = 0; i < sz; i++) { DEBUG_printf("%p ", a[i]); } DEBUG_printf("\n"); -#endif } +#else +#define dump_args(...) (void)0 +#endif // If it's possible to call a function without allocating new argument array, // this function returns true, together with pointers to 2 subarrays to be used diff --git a/py/objgenerator.c b/py/objgenerator.c index 8f6bb17cfd..78694c866b 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -127,13 +127,16 @@ STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_o switch (mp_obj_gen_resume(self_in, send_value, throw_value, &ret)) { case MP_VM_RETURN_NORMAL: // Optimize return w/o value in case generator is used in for loop - if (ret == mp_const_none) { + if (ret == mp_const_none || ret == MP_OBJ_NULL) { return MP_OBJ_NULL; } else { nlr_jump(mp_obj_new_exception_args(&mp_type_StopIteration, 1, &ret)); } case MP_VM_RETURN_YIELD: + if (throw_value != MP_OBJ_NULL && mp_obj_is_subclass_fast(mp_obj_get_type(throw_value), &mp_type_GeneratorExit)) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit")); + } return ret; case MP_VM_RETURN_EXCEPTION: @@ -171,13 +174,6 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in); STATIC mp_obj_t gen_instance_throw(uint n_args, const mp_obj_t *args) { mp_obj_t exc = (n_args == 2) ? args[1] : args[2]; exc = mp_make_raise_obj(exc); - if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_GeneratorExit)) { - // Throwing GeneratorExit is equivalent of calling close aka - // GeneratorExit should be handled specially - // TODO: Calling .close() will throw new exception instance, not one - // given to throw, which is not ok. - return gen_instance_close(args[0]); - } mp_obj_t ret = gen_resume_and_raise(args[0], mp_const_none, exc); if (ret == MP_OBJ_NULL) { diff --git a/py/objstr.c b/py/objstr.c index 751f93afd7..2ca2248b24 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -372,7 +372,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) { while (s < top && splits != 0) { start = s; while (s < top && !is_ws(*s)) s++; - mp_list_append(res, mp_obj_new_str(start, s - start, false)); + mp_obj_list_append(res, mp_obj_new_str(start, s - start, false)); if (s >= top) { break; } @@ -383,7 +383,7 @@ STATIC mp_obj_t str_split(uint n_args, const mp_obj_t *args) { } if (s < top) { - mp_list_append(res, mp_obj_new_str(s, top - s, false)); + mp_obj_list_append(res, mp_obj_new_str(s, top - s, false)); } return res; diff --git a/py/objtype.c b/py/objtype.c index 1275124803..ee3ce12abe 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -297,6 +297,10 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj STATIC void type_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_type)); mp_obj_type_t *self = self_in; + if (attr == MP_QSTR___name__) { + dest[0] = MP_OBJ_NEW_QSTR(self->name); + return; + } mp_obj_t member = mp_obj_class_lookup(self, attr); if (member != MP_OBJ_NULL) { // check if the methods are functions, static or class methods diff --git a/py/runtime.c b/py/runtime.c index f827fd831e..daa555e4a2 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -72,10 +72,6 @@ void mp_deinit(void) { mp_emit_glue_deinit(); } -mp_obj_t mp_list_append(mp_obj_t self_in, mp_obj_t arg) { - return mp_obj_list_append(self_in, arg); -} - mp_obj_t mp_load_const_dec(qstr qstr) { DEBUG_OP_printf("load '%s'\n", qstr_str(qstr)); uint len; @@ -136,14 +132,6 @@ mp_obj_t mp_load_build_class(void) { } } -mp_obj_t mp_get_cell(mp_obj_t cell) { - return mp_obj_cell_get(cell); -} - -void mp_set_cell(mp_obj_t cell, mp_obj_t val) { - mp_obj_cell_set(cell, val); -} - void mp_store_name(qstr qstr, mp_obj_t obj) { DEBUG_OP_printf("store name %s <- %p\n", qstr_str(qstr), obj); mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj; @@ -656,23 +644,6 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, uint n_args_n_kw, const mp_obj_ return res; } -mp_obj_t mp_build_tuple(int n_args, mp_obj_t *items) { - return mp_obj_new_tuple(n_args, items); -} - -mp_obj_t mp_build_list(int n_args, mp_obj_t *items) { - return mp_obj_new_list(n_args, items); -} - -mp_obj_t mp_build_set(int n_args, mp_obj_t *items) { - return mp_obj_new_set(n_args, items); -} - -mp_obj_t mp_store_set(mp_obj_t set, mp_obj_t item) { - mp_obj_set_store(set, item); - return set; -} - // unpacked items are stored in reverse order into the array pointed to by items void mp_unpack_sequence(mp_obj_t seq_in, uint num, mp_obj_t *items) { uint seq_len; @@ -713,15 +684,6 @@ too_long: nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", num)); } -mp_obj_t mp_build_map(int n_args) { - return mp_obj_new_dict(n_args); -} - -mp_obj_t mp_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value) { - // map should always be a dict - return mp_obj_dict_store(map, key, value); -} - mp_obj_t mp_load_attr(mp_obj_t base, qstr attr) { DEBUG_OP_printf("load attr %p.%s\n", base, qstr_str(attr)); // use load_method @@ -915,6 +877,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { // TODO: Unclear what to do with StopIterarion exception here. mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) { + assert((send_value != MP_OBJ_NULL) ^ (throw_value != MP_OBJ_NULL)); mp_obj_type_t *type = mp_obj_get_type(self_in); if (type == &mp_type_gen_instance) { @@ -960,9 +923,20 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th return MP_VM_RETURN_NORMAL; } } - mp_load_method(self_in, MP_QSTR_throw, dest); - *ret_val = mp_call_method_n_kw(1, 0, &throw_value); - return MP_VM_RETURN_YIELD; + mp_load_method_maybe(self_in, MP_QSTR_throw, dest); + if (dest[0] != MP_OBJ_NULL) { + *ret_val = mp_call_method_n_kw(1, 0, &throw_value); + // If .throw() method returned, we assume it's value to yield + // - any exception would be thrown with nlr_jump(). + return MP_VM_RETURN_YIELD; + } + // If there's nowhere to throw exception into, then we assume that object + // is just incapable to handle it, so any exception thrown into it + // will be propagated up. This behavior is approved by test_pep380.py + // test_delegation_of_close_to_non_generator(), + // test_delegating_throw_to_non_generator() + *ret_val = throw_value; + return MP_VM_RETURN_EXCEPTION; } assert(0); @@ -1057,13 +1031,13 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = { mp_obj_is_true, mp_unary_op, mp_binary_op, - mp_build_tuple, - mp_build_list, - mp_list_append, - mp_build_map, - mp_store_map, - mp_build_set, - mp_store_set, + mp_obj_new_tuple, + mp_obj_new_list, + mp_obj_list_append, + mp_obj_new_dict, + mp_obj_dict_store, + mp_obj_new_set, + mp_obj_set_store, mp_make_function_from_id, mp_call_function_n_kw_for_native, mp_call_method_n_kw, diff --git a/py/runtime.h b/py/runtime.h index d71e045b01..b817d61aec 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -28,14 +28,11 @@ mp_obj_t mp_load_const_dec(qstr qstr); mp_obj_t mp_load_const_str(qstr qstr); mp_obj_t mp_load_const_bytes(qstr qstr); -mp_obj_t mp_get_cell(mp_obj_t cell); -void mp_set_cell(mp_obj_t cell, mp_obj_t val); - -mp_obj_t mp_make_function_from_id(uint unique_code_id, bool free_unique_code, mp_obj_t def_args); +mp_obj_t mp_make_function_from_id(uint unique_code_id, bool free_unique_code, mp_obj_t def_args, mp_obj_t def_kw_args); mp_obj_t mp_make_function_n(int n_args, void *fun); // fun must have the correct signature for n_args fixed arguments mp_obj_t mp_make_function_var(int n_args_min, mp_fun_var_t fun); mp_obj_t mp_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun); // min and max are inclusive -mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args); +mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args); mp_obj_t mp_call_function_0(mp_obj_t fun); mp_obj_t mp_call_function_1(mp_obj_t fun, mp_obj_t arg); @@ -45,13 +42,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun, uint n_args, uint n_kw, const mp_ob mp_obj_t mp_call_method_n_kw(uint n_args, uint n_kw, const mp_obj_t *args); mp_obj_t mp_call_method_n_kw_var(bool have_self, uint n_args_n_kw, const mp_obj_t *args); -mp_obj_t mp_build_tuple(int n_args, mp_obj_t *items); -mp_obj_t mp_build_list(int n_args, mp_obj_t *items); -mp_obj_t mp_list_append(mp_obj_t list, mp_obj_t arg); -mp_obj_t mp_build_set(int n_args, mp_obj_t *items); -mp_obj_t mp_store_set(mp_obj_t set, mp_obj_t item); void mp_unpack_sequence(mp_obj_t seq, uint num, mp_obj_t *items); -mp_obj_t mp_build_map(int n_args); mp_obj_t mp_store_map(mp_obj_t map, mp_obj_t key, mp_obj_t value); mp_obj_t mp_load_attr(mp_obj_t base, qstr attr); void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest); @@ -243,7 +243,7 @@ dispatch_loop: case MP_BC_LOAD_DEREF: DECODE_UINT; - PUSH(mp_get_cell(fastn[-unum])); + PUSH(mp_obj_cell_get(fastn[-unum])); break; case MP_BC_LOAD_NAME: @@ -290,7 +290,7 @@ dispatch_loop: case MP_BC_STORE_DEREF: DECODE_UINT; - mp_set_cell(fastn[-unum], POP()); + mp_obj_cell_set(fastn[-unum], POP()); break; case MP_BC_STORE_NAME: @@ -580,49 +580,49 @@ unwind_jump: case MP_BC_BUILD_TUPLE: DECODE_UINT; sp -= unum - 1; - SET_TOP(mp_build_tuple(unum, sp)); + SET_TOP(mp_obj_new_tuple(unum, sp)); break; case MP_BC_BUILD_LIST: DECODE_UINT; sp -= unum - 1; - SET_TOP(mp_build_list(unum, sp)); + SET_TOP(mp_obj_new_list(unum, sp)); break; case MP_BC_LIST_APPEND: DECODE_UINT; // I think it's guaranteed by the compiler that sp[unum] is a list - mp_list_append(sp[-unum], sp[0]); + mp_obj_list_append(sp[-unum], sp[0]); sp--; break; case MP_BC_BUILD_MAP: DECODE_UINT; - PUSH(mp_build_map(unum)); + PUSH(mp_obj_new_dict(unum)); break; case MP_BC_STORE_MAP: sp -= 2; - mp_store_map(sp[0], sp[2], sp[1]); + mp_obj_dict_store(sp[0], sp[2], sp[1]); break; case MP_BC_MAP_ADD: DECODE_UINT; // I think it's guaranteed by the compiler that sp[-unum - 1] is a map - mp_store_map(sp[-unum - 1], sp[0], sp[-1]); + mp_obj_dict_store(sp[-unum - 1], sp[0], sp[-1]); sp -= 2; break; case MP_BC_BUILD_SET: DECODE_UINT; sp -= unum - 1; - SET_TOP(mp_build_set(unum, sp)); + SET_TOP(mp_obj_new_set(unum, sp)); break; case MP_BC_SET_ADD: DECODE_UINT; // I think it's guaranteed by the compiler that sp[-unum] is a set - mp_store_set(sp[-unum], sp[0]); + mp_obj_set_store(sp[-unum], sp[0]); sp--; break; @@ -648,23 +648,28 @@ unwind_jump: case MP_BC_MAKE_FUNCTION: DECODE_UINT; - PUSH(mp_make_function_from_id(unum, false, MP_OBJ_NULL)); + PUSH(mp_make_function_from_id(unum, false, MP_OBJ_NULL, MP_OBJ_NULL)); break; case MP_BC_MAKE_FUNCTION_DEFARGS: DECODE_UINT; - SET_TOP(mp_make_function_from_id(unum, false, TOP())); + // Stack layout: def_dict def_tuple <- TOS + obj1 = POP(); + SET_TOP(mp_make_function_from_id(unum, false, obj1, TOP())); break; case MP_BC_MAKE_CLOSURE: DECODE_UINT; - SET_TOP(mp_make_closure_from_id(unum, TOP(), MP_OBJ_NULL)); + // Stack layout: closure_tuple <- TOS + SET_TOP(mp_make_closure_from_id(unum, TOP(), MP_OBJ_NULL, MP_OBJ_NULL)); break; case MP_BC_MAKE_CLOSURE_DEFARGS: DECODE_UINT; + // Stack layout: def_dict def_tuple closure_tuple <- TOS obj1 = POP(); - SET_TOP(mp_make_closure_from_id(unum, obj1, TOP())); + obj2 = POP(); + SET_TOP(mp_make_closure_from_id(unum, obj1, obj2, TOP())); break; case MP_BC_CALL_FUNCTION: @@ -764,7 +769,7 @@ yield: if (inject_exc != MP_OBJ_NULL) { t_exc = inject_exc; inject_exc = MP_OBJ_NULL; - ret_kind = mp_resume(TOP(), mp_const_none, t_exc, &obj2); + ret_kind = mp_resume(TOP(), MP_OBJ_NULL, t_exc, &obj2); } else { ret_kind = mp_resume(TOP(), obj1, MP_OBJ_NULL, &obj2); } @@ -10,6 +10,10 @@ #define ROUND_ALLOC(a) (((a) & ((~0) - 7)) + 8) void vstr_init(vstr_t *vstr, int alloc) { + if (alloc < 2) { + // need at least 1 byte for the null byte at the end + alloc = 2; + } vstr->alloc = alloc; vstr->len = 0; vstr->buf = m_new(char, vstr->alloc); |