@@ -530,56 +530,6 @@ STATIC void emit_post_push_reg_reg_reg_reg(emit_t *emit, vtype_kind_t vtypea, in
530530 emit_post_push_reg (emit , vtyped , regd );
531531}
532532
533- // vtype of all n_pop objects is VTYPE_PYOBJ
534- // does not use any temporary registers (but may use reg_dest before loading it with stack pointer)
535- // TODO this needs some thinking for viper code
536- STATIC void emit_get_stack_pointer_to_reg_for_pop (emit_t * emit , int reg_dest , int n_pop ) {
537- need_reg_all (emit );
538- for (int i = 0 ; i < n_pop ; i ++ ) {
539- stack_info_t * si = & emit -> stack_info [emit -> stack_size - 1 - i ];
540- // must push any imm's to stack
541- // must convert them to VTYPE_PYOBJ for viper code
542- if (si -> kind == STACK_IMM ) {
543- si -> kind = STACK_VALUE ;
544- switch (si -> vtype ) {
545- case VTYPE_PYOBJ :
546- ASM_MOV_IMM_TO_LOCAL_USING (si -> u_imm , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
547- break ;
548- case VTYPE_BOOL :
549- si -> vtype = VTYPE_PYOBJ ;
550- if (si -> u_imm == 0 ) {
551- ASM_MOV_IMM_TO_LOCAL_USING ((mp_uint_t )mp_const_false , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
552- } else {
553- ASM_MOV_IMM_TO_LOCAL_USING ((mp_uint_t )mp_const_true , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
554- }
555- break ;
556- case VTYPE_INT :
557- si -> vtype = VTYPE_PYOBJ ;
558- ASM_MOV_IMM_TO_LOCAL_USING ((si -> u_imm << 1 ) | 1 , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
559- break ;
560- default :
561- // not handled
562- assert (0 );
563- }
564- }
565- assert (si -> kind == STACK_VALUE );
566- assert (si -> vtype == VTYPE_PYOBJ );
567- }
568- adjust_stack (emit , - n_pop );
569- ASM_MOV_LOCAL_ADDR_TO_REG (emit -> stack_start + emit -> stack_size , reg_dest );
570- }
571-
572- // vtype of all n_push objects is VTYPE_PYOBJ
573- STATIC void emit_get_stack_pointer_to_reg_for_push (emit_t * emit , int reg_dest , int n_push ) {
574- need_reg_all (emit );
575- for (int i = 0 ; i < n_push ; i ++ ) {
576- emit -> stack_info [emit -> stack_size + i ].kind = STACK_VALUE ;
577- emit -> stack_info [emit -> stack_size + i ].vtype = VTYPE_PYOBJ ;
578- }
579- ASM_MOV_LOCAL_ADDR_TO_REG (emit -> stack_start + emit -> stack_size , reg_dest );
580- adjust_stack (emit , n_push );
581- }
582-
583533STATIC void emit_call (emit_t * emit , mp_fun_kind_t fun_kind , void * fun ) {
584534 need_reg_all (emit );
585535#if N_X64
@@ -634,26 +584,84 @@ STATIC void emit_call_with_3_imm_args_and_first_aligned(emit_t *emit, mp_fun_kin
634584#endif
635585}
636586
637- STATIC void emit_native_load_id ( emit_t * emit , qstr qstr ) {
638- // check for built-ins
639- if ( strcmp ( qstr_str ( qstr ), "v_int" ) == 0 ) {
640- assert ( 0 );
641- emit_native_pre ( emit );
642- //emit_post_push_blank (emit, VTYPE_BUILTIN_V_INT );
587+ // vtype of all n_pop objects is VTYPE_PYOBJ
588+ // Will convert any items that are not VTYPE_PYOBJ to this type and put them back on the stack.
589+ // If any conversions of non-immediate values are needed, then it uses REG_ARG_1, REG_ARG_2 and REG_RET.
590+ // Otherwise, it does not use any temporary registers (but may use reg_dest before loading it with stack pointer).
591+ STATIC void emit_get_stack_pointer_to_reg_for_pop ( emit_t * emit , mp_uint_t reg_dest , mp_uint_t n_pop ) {
592+ need_reg_all (emit );
643593
644- // not a built-in, so do usual thing
645- } else {
646- emit_common_load_id (emit , & EXPORT_FUN (method_table ), emit -> scope , qstr );
594+ // First, store any immediate values to their respective place on the stack.
595+ for (mp_uint_t i = 0 ; i < n_pop ; i ++ ) {
596+ stack_info_t * si = & emit -> stack_info [emit -> stack_size - 1 - i ];
597+ // must push any imm's to stack
598+ // must convert them to VTYPE_PYOBJ for viper code
599+ if (si -> kind == STACK_IMM ) {
600+ si -> kind = STACK_VALUE ;
601+ switch (si -> vtype ) {
602+ case VTYPE_PYOBJ :
603+ ASM_MOV_IMM_TO_LOCAL_USING (si -> u_imm , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
604+ break ;
605+ case VTYPE_BOOL :
606+ if (si -> u_imm == 0 ) {
607+ ASM_MOV_IMM_TO_LOCAL_USING ((mp_uint_t )mp_const_false , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
608+ } else {
609+ ASM_MOV_IMM_TO_LOCAL_USING ((mp_uint_t )mp_const_true , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
610+ }
611+ si -> vtype = VTYPE_PYOBJ ;
612+ break ;
613+ case VTYPE_INT :
614+ case VTYPE_UINT :
615+ ASM_MOV_IMM_TO_LOCAL_USING ((si -> u_imm << 1 ) | 1 , emit -> stack_start + emit -> stack_size - 1 - i , reg_dest );
616+ si -> vtype = VTYPE_PYOBJ ;
617+ break ;
618+ default :
619+ // not handled
620+ assert (0 );
621+ }
622+ }
623+
624+ // verify that this value is on the stack
625+ assert (si -> kind == STACK_VALUE );
626+ }
627+
628+ // Second, convert any non-VTYPE_PYOBJ to that type.
629+ for (mp_uint_t i = 0 ; i < n_pop ; i ++ ) {
630+ stack_info_t * si = & emit -> stack_info [emit -> stack_size - 1 - i ];
631+ if (si -> vtype != VTYPE_PYOBJ ) {
632+ mp_uint_t local_num = emit -> stack_start + emit -> stack_size - 1 - i ;
633+ ASM_MOV_LOCAL_TO_REG (local_num , REG_ARG_1 );
634+ emit_call_with_imm_arg (emit , MP_F_CONVERT_NATIVE_TO_OBJ , mp_convert_native_to_obj , si -> vtype , REG_ARG_2 ); // arg2 = type
635+ ASM_MOV_REG_TO_LOCAL (REG_RET , local_num );
636+ si -> vtype = VTYPE_PYOBJ ;
637+ }
638+ }
639+
640+ // Adujust the stack for a pop of n_pop items, and load the stack pointer into reg_dest.
641+ adjust_stack (emit , - n_pop );
642+ ASM_MOV_LOCAL_ADDR_TO_REG (emit -> stack_start + emit -> stack_size , reg_dest );
643+ }
644+
645+ // vtype of all n_push objects is VTYPE_PYOBJ
646+ STATIC void emit_get_stack_pointer_to_reg_for_push (emit_t * emit , mp_uint_t reg_dest , mp_uint_t n_push ) {
647+ need_reg_all (emit );
648+ for (mp_uint_t i = 0 ; i < n_push ; i ++ ) {
649+ emit -> stack_info [emit -> stack_size + i ].kind = STACK_VALUE ;
650+ emit -> stack_info [emit -> stack_size + i ].vtype = VTYPE_PYOBJ ;
647651 }
652+ ASM_MOV_LOCAL_ADDR_TO_REG (emit -> stack_start + emit -> stack_size , reg_dest );
653+ adjust_stack (emit , n_push );
654+ }
655+
656+ STATIC void emit_native_load_id (emit_t * emit , qstr qstr ) {
657+ emit_common_load_id (emit , & EXPORT_FUN (method_table ), emit -> scope , qstr );
648658}
649659
650660STATIC void emit_native_store_id (emit_t * emit , qstr qstr ) {
651- // TODO check for built-ins and disallow
652661 emit_common_store_id (emit , & EXPORT_FUN (method_table ), emit -> scope , qstr );
653662}
654663
655664STATIC void emit_native_delete_id (emit_t * emit , qstr qstr ) {
656- // TODO check for built-ins and disallow
657665 emit_common_delete_id (emit , & EXPORT_FUN (method_table ), emit -> scope , qstr );
658666}
659667
@@ -1396,7 +1404,7 @@ STATIC void emit_native_call_function(emit_t *emit, int n_positional, int n_keyw
13961404 vtype_kind_t vtype_fun ;
13971405 emit_pre_pop_reg (emit , & vtype_fun , REG_ARG_1 ); // the function
13981406 assert (vtype_fun == VTYPE_PYOBJ );
1399- 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 );
1407+ emit_call_with_imm_arg (emit , MP_F_NATIVE_CALL_FUNCTION_N_KW , mp_native_call_function_n_kw , n_positional | (n_keyword << 8 ), REG_ARG_2 );
14001408 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
14011409}
14021410
@@ -1453,13 +1461,13 @@ STATIC void emit_native_return_value(emit_t *emit) {
14531461
14541462STATIC void emit_native_raise_varargs (emit_t * emit , int n_args ) {
14551463 assert (n_args == 1 );
1456- vtype_kind_t vtype_err ;
1457- emit_pre_pop_reg (emit , & vtype_err , REG_ARG_1 ); // arg1 = object to raise
1458- assert ( vtype_err == VTYPE_PYOBJ );
1459- emit_call ( emit , 0 , mp_make_raise_obj ); // TODO need to add function to runtime table
1460- emit_post_push_reg ( emit , VTYPE_PYOBJ , REG_RET );
1461- emit_pre_pop_reg ( emit , & vtype_err , REG_ARG_1 );
1462- emit_call (emit , 0 , nlr_jump ); // TODO need to add function to runtime table
1464+ vtype_kind_t vtype_exc ;
1465+ emit_pre_pop_reg (emit , & vtype_exc , REG_ARG_1 ); // arg1 = object to raise
1466+ if ( vtype_exc != VTYPE_PYOBJ ) {
1467+ printf ( "ViperTypeError: must raise an object\n" );
1468+ }
1469+ // TODO probably make this 1 call to the runtime (which could even call convert, native_raise(obj, type))
1470+ emit_call (emit , MP_F_NATIVE_RAISE , mp_native_raise );
14631471}
14641472
14651473STATIC void emit_native_yield_value (emit_t * emit ) {
0 commit comments