3434#include "obj.h"
3535#include "runtime.h"
3636
37+ #if 0 // print debugging info
38+ #define DEBUG_PRINT (1)
39+ #define DEBUG_printf DEBUG_printf
40+ #else // don't print debugging info
41+ #define DEBUG_printf (...) (void)0
42+ #endif
43+
3744// wrapper around everything in this file
3845#if (MICROPY_EMIT_X64 && N_X64 ) || (MICROPY_EMIT_THUMB && N_THUMB )
3946
@@ -300,6 +307,7 @@ STATIC void emit_native_set_source_line(emit_t *emit, int source_line) {
300307}
301308
302309STATIC void adjust_stack (emit_t * emit , int stack_size_delta ) {
310+ DEBUG_printf ("adjust stack: stack:%d + delta:%d\n" , emit -> stack_size , stack_size_delta );
303311 emit -> stack_size += stack_size_delta ;
304312 assert (emit -> stack_size >= 0 );
305313 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
542550#endif
543551}
544552
553+ 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 ) {
554+ need_reg_all (emit );
555+ ASM_MOV_IMM_TO_REG (arg_val1 , arg_reg1 );
556+ ASM_MOV_IMM_TO_REG (arg_val2 , arg_reg2 );
557+ ASM_MOV_IMM_TO_REG (arg_val3 , arg_reg3 );
558+ #if N_X64
559+ asm_x64_call_ind (emit -> as , fun , REG_RAX );
560+ #elif N_THUMB
561+ asm_thumb_bl_ind (emit -> as , mp_fun_table [fun_kind ], fun_kind , REG_R3 );
562+ #endif
563+ }
564+
545565STATIC void emit_native_load_id (emit_t * emit , qstr qstr ) {
546566 // check for built-ins
547567 if (strcmp (qstr_str (qstr ), "v_int" ) == 0 ) {
@@ -577,22 +597,38 @@ STATIC void emit_native_label_assign(emit_t *emit, int l) {
577597 emit_post (emit );
578598}
579599
580- STATIC void emit_native_import_name (emit_t * emit , qstr qstr ) {
581- // not implemented
582- assert (0 );
600+ STATIC void emit_native_import_name (emit_t * emit , qstr qst ) {
601+ DEBUG_printf ("import_name %s\n" , qstr_str (qst ));
602+ vtype_kind_t vtype_fromlist ;
603+ vtype_kind_t vtype_level ;
604+ emit_pre_pop_reg_reg (emit , & vtype_fromlist , REG_ARG_2 , & vtype_level , REG_ARG_3 ); // arg2 = fromlist, arg3 = level
605+ assert (vtype_fromlist == VTYPE_PYOBJ );
606+ assert (vtype_level == VTYPE_PYOBJ );
607+ emit_call_with_imm_arg (emit , MP_F_IMPORT_NAME , mp_import_name , qst , REG_ARG_1 ); // arg1 = import name
608+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
583609}
584610
585- STATIC void emit_native_import_from (emit_t * emit , qstr qstr ) {
586- // not implemented
587- assert (0 );
611+ STATIC void emit_native_import_from (emit_t * emit , qstr qst ) {
612+ DEBUG_printf ("import_from %s\n" , qstr_str (qst ));
613+ emit_native_pre (emit );
614+ vtype_kind_t vtype_module ;
615+ emit_access_stack (emit , 1 , & vtype_module , REG_ARG_1 ); // arg1 = module
616+ assert (vtype_module == VTYPE_PYOBJ );
617+ emit_call_with_imm_arg (emit , MP_F_IMPORT_FROM , mp_import_from , qst , REG_ARG_2 ); // arg2 = import name
618+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
588619}
589620
590621STATIC void emit_native_import_star (emit_t * emit ) {
591- // not implemented
592- assert (0 );
622+ DEBUG_printf ("import_star\n" );
623+ vtype_kind_t vtype_module ;
624+ emit_pre_pop_reg (emit , & vtype_module , REG_ARG_1 ); // arg1 = module
625+ assert (vtype_module == VTYPE_PYOBJ );
626+ emit_call (emit , MP_F_IMPORT_ALL , mp_import_all );
627+ emit_post (emit );
593628}
594629
595630STATIC void emit_native_load_const_tok (emit_t * emit , mp_token_kind_t tok ) {
631+ DEBUG_printf ("load_const_tok %d\n" , tok );
596632 emit_native_pre (emit );
597633 int vtype ;
598634 machine_uint_t val ;
@@ -616,6 +652,7 @@ STATIC void emit_native_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
616652}
617653
618654STATIC void emit_native_load_const_small_int (emit_t * emit , machine_int_t arg ) {
655+ DEBUG_printf ("load_const_small_int %d\n" , arg );
619656 emit_native_pre (emit );
620657 if (emit -> do_viper_types ) {
621658 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) {
624661 }
625662}
626663
627- STATIC void emit_native_load_const_int (emit_t * emit , qstr qstr ) {
628- // not implemented
629- // load integer, check fits in 32 bits
630- assert (0 );
664+ STATIC void emit_native_load_const_int (emit_t * emit , qstr qst ) {
665+ DEBUG_printf ("load_const_int %s\n" , qstr_str (st ));
666+ // for viper: load integer, check fits in 32 bits
667+ emit_native_pre (emit );
668+ emit_call_with_imm_arg (emit , MP_F_LOAD_CONST_INT , mp_obj_new_int_from_long_str , qst , REG_ARG_1 );
669+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
631670}
632671
633672STATIC 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) {
11251164}
11261165
11271166STATIC void emit_native_build_slice (emit_t * emit , int n_args ) {
1128- assert (0 );
1167+ DEBUG_printf ("build_slice %d\n" , n_args );
1168+ assert (n_args == 2 );
1169+ vtype_kind_t vtype_start , vtype_stop ;
1170+ emit_pre_pop_reg_reg (emit , & vtype_stop , REG_ARG_2 , & vtype_start , REG_ARG_1 ); // arg1 = start, arg2 = stop
1171+ assert (vtype_start == VTYPE_PYOBJ );
1172+ assert (vtype_stop == VTYPE_PYOBJ );
1173+ 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
1174+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
11291175}
1176+
11301177STATIC void emit_native_unpack_sequence (emit_t * emit , int n_args ) {
1131- // call runtime, needs type decl
1132- assert (0 );
1178+ // TODO this is untested
1179+ DEBUG_printf ("unpack_sequence %d\n" , n_args );
1180+ vtype_kind_t vtype_base ;
1181+ emit_pre_pop_reg (emit , & vtype_base , REG_ARG_1 ); // arg1 = seq
1182+ assert (vtype_base == VTYPE_PYOBJ );
1183+ emit_get_stack_pointer_to_reg_for_push (emit , REG_ARG_3 , n_args ); // arg3 = dest ptr
1184+ emit_call_with_imm_arg (emit , MP_F_UNPACK_SEQUENCE , mp_unpack_sequence , n_args , REG_ARG_2 ); // arg2 = n_args
11331185}
1186+
11341187STATIC void emit_native_unpack_ex (emit_t * emit , int n_left , int n_right ) {
11351188 assert (0 );
11361189}
@@ -1139,7 +1192,7 @@ STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, uint n_pos_d
11391192 // call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them
11401193 assert (n_pos_defaults == 0 && n_kw_defaults == 0 );
11411194 emit_native_pre (emit );
1142- emit_call_with_imm_arg (emit , MP_F_MAKE_FUNCTION_FROM_ID , mp_make_function_from_id , scope -> unique_code_id , REG_ARG_1 );
1195+ 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 );
11431196 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
11441197}
11451198
@@ -1149,7 +1202,7 @@ STATIC void emit_native_make_closure(emit_t *emit, scope_t *scope, uint n_pos_de
11491202
11501203STATIC void emit_native_call_function (emit_t * emit , int n_positional , int n_keyword , bool have_star_arg , bool have_dbl_star_arg ) {
11511204 // call special viper runtime routine with type info for args, and wanted type info for return
1152- assert (n_keyword == 0 && !have_star_arg && !have_dbl_star_arg );
1205+ assert (!have_star_arg && !have_dbl_star_arg );
11531206
11541207 /* we no longer have these _n specific call_function's
11551208 * 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
11761229 */
11771230
11781231 emit_native_pre (emit );
1179- if (n_positional != 0 ) {
1180- emit_get_stack_pointer_to_reg_for_pop (emit , REG_ARG_3 , n_positional ); // pointer to args
1232+ if (n_positional != 0 || n_keyword != 0 ) {
1233+ emit_get_stack_pointer_to_reg_for_pop (emit , REG_ARG_3 , n_positional + 2 * n_keyword ); // pointer to args
11811234 }
11821235 vtype_kind_t vtype_fun ;
11831236 emit_pre_pop_reg (emit , & vtype_fun , REG_ARG_1 ); // the function
11841237 assert (vtype_fun == VTYPE_PYOBJ );
1185- 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 );
1238+ 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 );
11861239 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
11871240}
11881241
11891242STATIC void emit_native_call_method (emit_t * emit , int n_positional , int n_keyword , bool have_star_arg , bool have_dbl_star_arg ) {
1190- assert (n_keyword == 0 && !have_star_arg && !have_dbl_star_arg );
1243+ assert (!have_star_arg && !have_dbl_star_arg );
11911244
11921245 /*
11931246 if (n_positional == 0) {
@@ -1207,12 +1260,13 @@ STATIC void emit_native_call_method(emit_t *emit, int n_positional, int n_keywor
12071260 */
12081261
12091262 emit_native_pre (emit );
1210- emit_get_stack_pointer_to_reg_for_pop (emit , REG_ARG_3 , n_positional + 2 ); // pointer to items, including meth and self
1263+ 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
12111264 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 );
12121265 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
12131266}
12141267
12151268STATIC void emit_native_return_value (emit_t * emit ) {
1269+ DEBUG_printf ("return_value\n" );
12161270 // easy. since we don't know who we return to, just return the raw value.
12171271 // runtime needs then to know our type signature, but I think that's possible.
12181272 vtype_kind_t vtype ;
0 commit comments