diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/compile.c | 2 | ||||
-rw-r--r-- | py/emitglue.c | 21 | ||||
-rw-r--r-- | py/emitnative.c | 98 | ||||
-rw-r--r-- | py/runtime.c | 6 | ||||
-rw-r--r-- | py/runtime.h | 3 | ||||
-rw-r--r-- | py/runtime0.h | 6 | ||||
-rw-r--r-- | py/vm.c | 4 |
7 files changed, 106 insertions, 34 deletions
diff --git a/py/compile.c b/py/compile.c index 62c07cfd8c..f1870bf36e 100644 --- a/py/compile.c +++ b/py/compile.c @@ -3351,7 +3351,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is #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, MP_OBJ_NULL); + return mp_make_function_from_id_and_free(unique_code_id, MP_OBJ_NULL, MP_OBJ_NULL); #endif } } diff --git a/py/emitglue.c b/py/emitglue.c index dc084e159c..48800bbf00 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -190,7 +190,7 @@ 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 def_kw_args) { +mp_obj_t mp_make_function_from_id(uint unique_code_id, 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 @@ -224,20 +224,25 @@ mp_obj_t mp_make_function_from_id(uint unique_code_id, bool free_unique_code, mp fun = mp_obj_new_gen_wrap(fun); } + return fun; +} + +mp_obj_t mp_make_function_from_id_and_free(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args) { + mp_obj_t f = mp_make_function_from_id(unique_code_id, def_args, def_kw_args); + // in some cases we can free the unique_code slot - // any dynamically allocade memory is now owned by the fun object - if (free_unique_code) { - memset(c, 0, sizeof *c); // make sure all pointers are zeroed - c->kind = MP_CODE_UNUSED; - } + // any dynamically allocated memory is now owned by the fun object + mp_code_t *c = &unique_codes[unique_code_id]; + memset(c, 0, sizeof *c); // make sure all pointers are zeroed + c->kind = MP_CODE_UNUSED; - return fun; + return f; } 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, def_kw_args); + mp_obj_t ffun = mp_make_function_from_id(unique_code_id, 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 524c5caa75..af8b35f45d 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -34,6 +34,13 @@ #include "obj.h" #include "runtime.h" +#if 0 // print debugging info +#define DEBUG_PRINT (1) +#define DEBUG_printf DEBUG_printf +#else // don't print debugging info +#define DEBUG_printf(...) (void)0 +#endif + // wrapper around everything in this file #if (MICROPY_EMIT_X64 && N_X64) || (MICROPY_EMIT_THUMB && N_THUMB) @@ -300,6 +307,7 @@ STATIC void emit_native_set_source_line(emit_t *emit, int source_line) { } STATIC void adjust_stack(emit_t *emit, int stack_size_delta) { + DEBUG_printf("adjust stack: stack:%d + delta:%d\n", emit->stack_size, stack_size_delta); emit->stack_size += stack_size_delta; assert(emit->stack_size >= 0); if (emit->pass > PASS_1 && emit->stack_size > emit->scope->stack_size) { @@ -542,6 +550,18 @@ STATIC void emit_call_with_2_imm_args(emit_t *emit, mp_fun_kind_t fun_kind, void #endif } +STATIC void emit_call_with_3_imm_args(emit_t *emit, mp_fun_kind_t fun_kind, void *fun, machine_int_t arg_val1, int arg_reg1, machine_int_t arg_val2, int arg_reg2, machine_int_t arg_val3, int arg_reg3) { + need_reg_all(emit); + ASM_MOV_IMM_TO_REG(arg_val1, arg_reg1); + ASM_MOV_IMM_TO_REG(arg_val2, arg_reg2); + ASM_MOV_IMM_TO_REG(arg_val3, arg_reg3); +#if N_X64 + asm_x64_call_ind(emit->as, fun, REG_RAX); +#elif N_THUMB + asm_thumb_bl_ind(emit->as, mp_fun_table[fun_kind], fun_kind, REG_R3); +#endif +} + STATIC void emit_native_load_id(emit_t *emit, qstr qstr) { // check for built-ins if (strcmp(qstr_str(qstr), "v_int") == 0) { @@ -577,22 +597,38 @@ STATIC void emit_native_label_assign(emit_t *emit, int l) { emit_post(emit); } -STATIC void emit_native_import_name(emit_t *emit, qstr qstr) { - // not implemented - assert(0); +STATIC void emit_native_import_name(emit_t *emit, qstr qst) { + DEBUG_printf("import_name %s\n", qstr_str(qst)); + vtype_kind_t vtype_fromlist; + vtype_kind_t vtype_level; + emit_pre_pop_reg_reg(emit, &vtype_fromlist, REG_ARG_2, &vtype_level, REG_ARG_3); // arg2 = fromlist, arg3 = level + assert(vtype_fromlist == VTYPE_PYOBJ); + assert(vtype_level == VTYPE_PYOBJ); + emit_call_with_imm_arg(emit, MP_F_IMPORT_NAME, mp_import_name, qst, REG_ARG_1); // arg1 = import name + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } -STATIC void emit_native_import_from(emit_t *emit, qstr qstr) { - // not implemented - assert(0); +STATIC void emit_native_import_from(emit_t *emit, qstr qst) { + DEBUG_printf("import_from %s\n", qstr_str(qst)); + emit_native_pre(emit); + vtype_kind_t vtype_module; + emit_access_stack(emit, 1, &vtype_module, REG_ARG_1); // arg1 = module + assert(vtype_module == VTYPE_PYOBJ); + emit_call_with_imm_arg(emit, MP_F_IMPORT_FROM, mp_import_from, qst, REG_ARG_2); // arg2 = import name + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } STATIC void emit_native_import_star(emit_t *emit) { - // not implemented - assert(0); + DEBUG_printf("import_star\n"); + vtype_kind_t vtype_module; + emit_pre_pop_reg(emit, &vtype_module, REG_ARG_1); // arg1 = module + assert(vtype_module == VTYPE_PYOBJ); + emit_call(emit, MP_F_IMPORT_ALL, mp_import_all); + emit_post(emit); } STATIC void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) { + DEBUG_printf("load_const_tok %d\n", tok); emit_native_pre(emit); int vtype; machine_uint_t val; @@ -616,6 +652,7 @@ STATIC void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) { } STATIC void emit_native_load_const_small_int(emit_t *emit, machine_int_t arg) { + DEBUG_printf("load_const_small_int %d\n", arg); emit_native_pre(emit); if (emit->do_viper_types) { emit_post_push_imm(emit, VTYPE_INT, arg); @@ -624,10 +661,12 @@ STATIC void emit_native_load_const_small_int(emit_t *emit, machine_int_t arg) { } } -STATIC void emit_native_load_const_int(emit_t *emit, qstr qstr) { - // not implemented - // load integer, check fits in 32 bits - assert(0); +STATIC void emit_native_load_const_int(emit_t *emit, qstr qst) { + DEBUG_printf("load_const_int %s\n", qstr_str(st)); + // for viper: load integer, check fits in 32 bits + emit_native_pre(emit); + emit_call_with_imm_arg(emit, MP_F_LOAD_CONST_INT, mp_obj_new_int_from_long_str, qst, REG_ARG_1); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } STATIC void emit_native_load_const_dec(emit_t *emit, qstr qstr) { @@ -1125,12 +1164,26 @@ STATIC void emit_native_set_add(emit_t *emit, int set_index) { } STATIC void emit_native_build_slice(emit_t *emit, int n_args) { - assert(0); + DEBUG_printf("build_slice %d\n", n_args); + assert(n_args == 2); + vtype_kind_t vtype_start, vtype_stop; + emit_pre_pop_reg_reg(emit, &vtype_stop, REG_ARG_2, &vtype_start, REG_ARG_1); // arg1 = start, arg2 = stop + assert(vtype_start == VTYPE_PYOBJ); + assert(vtype_stop == VTYPE_PYOBJ); + emit_call_with_imm_arg(emit, MP_F_NEW_SLICE, mp_obj_new_slice, (machine_uint_t)MP_OBJ_NULL, REG_ARG_3); // arg3 = step + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } + STATIC void emit_native_unpack_sequence(emit_t *emit, int n_args) { - // call runtime, needs type decl - assert(0); + // TODO this is untested + DEBUG_printf("unpack_sequence %d\n", n_args); + vtype_kind_t vtype_base; + emit_pre_pop_reg(emit, &vtype_base, REG_ARG_1); // arg1 = seq + assert(vtype_base == VTYPE_PYOBJ); + emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_3, n_args); // arg3 = dest ptr + emit_call_with_imm_arg(emit, MP_F_UNPACK_SEQUENCE, mp_unpack_sequence, n_args, REG_ARG_2); // arg2 = n_args } + STATIC void emit_native_unpack_ex(emit_t *emit, int n_left, int n_right) { assert(0); } @@ -1139,7 +1192,7 @@ STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, uint n_pos_d // call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them assert(n_pos_defaults == 0 && n_kw_defaults == 0); emit_native_pre(emit); - emit_call_with_imm_arg(emit, MP_F_MAKE_FUNCTION_FROM_ID, mp_make_function_from_id, scope->unique_code_id, REG_ARG_1); + emit_call_with_3_imm_args(emit, MP_F_MAKE_FUNCTION_FROM_ID, mp_make_function_from_id, scope->unique_code_id, REG_ARG_1, (machine_uint_t)MP_OBJ_NULL, REG_ARG_2, (machine_uint_t)MP_OBJ_NULL, REG_ARG_3); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } @@ -1149,7 +1202,7 @@ STATIC void emit_native_make_closure(emit_t *emit, scope_t *scope, uint n_pos_de STATIC void emit_native_call_function(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) { // call special viper runtime routine with type info for args, and wanted type info for return - assert(n_keyword == 0 && !have_star_arg && !have_dbl_star_arg); + assert(!have_star_arg && !have_dbl_star_arg); /* we no longer have these _n specific call_function's * they anyway push args into an array @@ -1176,18 +1229,18 @@ STATIC void emit_native_call_function(emit_t *emit, int n_positional, int n_keyw */ emit_native_pre(emit); - if (n_positional != 0) { - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional); // pointer to args + if (n_positional != 0 || n_keyword != 0) { + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword); // pointer to args } vtype_kind_t vtype_fun; emit_pre_pop_reg(emit, &vtype_fun, REG_ARG_1); // the function assert(vtype_fun == VTYPE_PYOBJ); - emit_call_with_imm_arg(emit, MP_F_CALL_FUNCTION_N_KW_FOR_NATIVE, mp_call_function_n_kw_for_native, n_positional, REG_ARG_2); + emit_call_with_imm_arg(emit, MP_F_CALL_FUNCTION_N_KW_FOR_NATIVE, mp_call_function_n_kw_for_native, n_positional | (n_keyword << 8), REG_ARG_2); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } STATIC void emit_native_call_method(emit_t *emit, int n_positional, int n_keyword, bool have_star_arg, bool have_dbl_star_arg) { - assert(n_keyword == 0 && !have_star_arg && !have_dbl_star_arg); + assert(!have_star_arg && !have_dbl_star_arg); /* if (n_positional == 0) { @@ -1207,12 +1260,13 @@ STATIC void emit_native_call_method(emit_t *emit, int n_positional, int n_keywor */ emit_native_pre(emit); - emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2); // pointer to items, including meth and self + emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 2 + n_positional + 2 * n_keyword); // pointer to items, including meth and self emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW, mp_call_method_n_kw, n_positional, REG_ARG_1, n_keyword, REG_ARG_2); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } STATIC void emit_native_return_value(emit_t *emit) { + DEBUG_printf("return_value\n"); // easy. since we don't know who we return to, just return the raw value. // runtime needs then to know our type signature, but I think that's possible. vtype_kind_t vtype; diff --git a/py/runtime.c b/py/runtime.c index 1ab971de4c..44e0ded507 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1027,6 +1027,7 @@ void *m_malloc_fail(int num_bytes) { // these must correspond to the respective enum void *const mp_fun_table[MP_F_NUMBER_OF] = { mp_load_const_dec, + mp_obj_new_int_from_long_str, mp_load_const_str, mp_load_name, mp_load_global, @@ -1050,6 +1051,11 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = { mp_call_function_n_kw_for_native, mp_call_method_n_kw, mp_getiter, + mp_import_name, + mp_import_from, + mp_import_all, + mp_obj_new_slice, + mp_unpack_sequence, mp_iternext, }; diff --git a/py/runtime.h b/py/runtime.h index 8e59550af5..cc76186f4e 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -28,7 +28,8 @@ 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_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_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args); +mp_obj_t mp_make_function_from_id_and_free(uint unique_code_id, 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 diff --git a/py/runtime0.h b/py/runtime0.h index 8a78a2304b..be598c670e 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -65,6 +65,7 @@ typedef enum { typedef enum { MP_F_LOAD_CONST_DEC = 0, + MP_F_LOAD_CONST_INT, MP_F_LOAD_CONST_STR, MP_F_LOAD_NAME, MP_F_LOAD_GLOBAL, @@ -89,6 +90,11 @@ typedef enum { MP_F_CALL_METHOD_N_KW, MP_F_GETITER, MP_F_ITERNEXT, + MP_F_IMPORT_NAME, + MP_F_IMPORT_FROM, + MP_F_IMPORT_ALL, + MP_F_NEW_SLICE, + MP_F_UNPACK_SEQUENCE, MP_F_NUMBER_OF, } mp_fun_kind_t; @@ -653,14 +653,14 @@ unwind_jump: case MP_BC_MAKE_FUNCTION: DECODE_UINT; - PUSH(mp_make_function_from_id(unum, false, MP_OBJ_NULL, MP_OBJ_NULL)); + PUSH(mp_make_function_from_id(unum, MP_OBJ_NULL, MP_OBJ_NULL)); break; case MP_BC_MAKE_FUNCTION_DEFARGS: DECODE_UINT; // Stack layout: def_dict def_tuple <- TOS obj1 = POP(); - SET_TOP(mp_make_function_from_id(unum, false, obj1, TOP())); + SET_TOP(mp_make_function_from_id(unum, obj1, TOP())); break; case MP_BC_MAKE_CLOSURE: |