@@ -344,14 +344,22 @@ static void need_reg_single(emit_t *emit, int reg_needed) {
344344 }
345345}
346346
347- static void need_reg_all (emit_t * emit ) {
347+ static void need_reg_all (emit_t * emit , int num_stack_top_that_must_be_value ) {
348348 for (int i = 0 ; i < emit -> stack_size ; i ++ ) {
349349 stack_info_t * si = & emit -> stack_info [i ];
350350 if (si -> kind == STACK_REG ) {
351351 si -> kind = STACK_VALUE ;
352352 ASM_MOV_REG_TO_LOCAL (si -> u_reg , emit -> stack_start + i );
353353 }
354354 }
355+ // must do this after making all registers available because ASM_MOV_IMM_TO_LOCAL uses a temporary register
356+ for (int i = 0 ; i < num_stack_top_that_must_be_value ; i ++ ) {
357+ stack_info_t * si = & emit -> stack_info [emit -> stack_size - 1 - i ];
358+ if (si -> kind == STACK_IMM ) {
359+ si -> kind = STACK_VALUE ;
360+ ASM_MOV_IMM_TO_LOCAL (si -> u_imm , emit -> stack_start + emit -> stack_size - 1 - i );
361+ }
362+ }
355363}
356364
357365static void emit_pre_pop_reg (emit_t * emit , vtype_kind_t * vtype , int reg_dest ) {
@@ -427,18 +435,20 @@ static void emit_post_push_reg_reg_reg_reg(emit_t *emit, vtype_kind_t vtypea, in
427435
428436// vtype of all n_pop objects is VTYPE_PYOBJ
429437static void emit_get_stack_pointer_to_reg_for_pop (emit_t * emit , int reg_dest , int n_pop ) {
430- need_reg_all (emit );
438+ need_reg_all (emit , n_pop );
431439 for (int i = 0 ; i < n_pop ; i ++ ) {
432- assert (emit -> stack_info [emit -> stack_size + i ].vtype == VTYPE_PYOBJ );
440+ assert (emit -> stack_info [emit -> stack_size - 1 - i ].kind == STACK_VALUE );
441+ assert (emit -> stack_info [emit -> stack_size - 1 - i ].vtype == VTYPE_PYOBJ );
433442 }
434443 ASM_MOV_LOCAL_ADDR_TO_REG (emit -> stack_start + emit -> stack_size - 1 , reg_dest );
435444 adjust_stack (emit , - n_pop );
436445}
437446
438447// vtype of all n_push objects is VTYPE_PYOBJ
439448static void emit_get_stack_pointer_to_reg_for_push (emit_t * emit , int reg_dest , int n_push ) {
440- need_reg_all (emit );
449+ need_reg_all (emit , 0 );
441450 for (int i = 0 ; i < n_push ; i ++ ) {
451+ emit -> stack_info [emit -> stack_size + i ].kind = STACK_VALUE ;
442452 emit -> stack_info [emit -> stack_size + i ].vtype = VTYPE_PYOBJ ;
443453 }
444454 ASM_MOV_LOCAL_ADDR_TO_REG (emit -> stack_start + emit -> stack_size + n_push - 1 , reg_dest );
@@ -454,7 +464,7 @@ static void emit_call(emit_t *emit, rt_fun_kind_t fun_kind, void *fun) {
454464}
455465
456466static void emit_call_with_imm_arg (emit_t * emit , rt_fun_kind_t fun_kind , void * fun , machine_int_t arg_val , int arg_reg ) {
457- need_reg_all (emit );
467+ need_reg_all (emit , 0 );
458468 ASM_MOV_IMM_TO_REG (arg_val , arg_reg );
459469 emit_call (emit , fun_kind , fun );
460470}
@@ -549,8 +559,13 @@ static void emit_native_load_const_dec(emit_t *emit, qstr qstr) {
549559}
550560
551561static void emit_native_load_const_id (emit_t * emit , qstr qstr ) {
552- // not supported for viper?
553- assert (0 );
562+ emit_pre (emit );
563+ if (emit -> do_viper_types ) {
564+ assert (0 );
565+ } else {
566+ emit_call_with_imm_arg (emit , RT_F_LOAD_CONST_STR , rt_load_const_str , qstr , REG_ARG_1 ); // TODO
567+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
568+ }
554569}
555570
556571static void emit_native_load_const_str (emit_t * emit , qstr qstr , bool bytes ) {
@@ -669,8 +684,9 @@ static void emit_native_load_method(emit_t *emit, qstr qstr) {
669684}
670685
671686static void emit_native_load_build_class (emit_t * emit ) {
672- // not supported
673- assert (0 );
687+ emit_pre (emit );
688+ emit_call (emit , RT_F_LOAD_BUILD_CLASS , rt_load_build_class );
689+ emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
674690}
675691
676692static void emit_native_store_fast (emit_t * emit , qstr qstr , int local_num ) {
@@ -727,8 +743,12 @@ static void emit_native_store_deref(emit_t *emit, qstr qstr) {
727743}
728744
729745static void emit_native_store_attr (emit_t * emit , qstr qstr ) {
730- // not implemented
731- assert (0 );
746+ vtype_kind_t vtype_base , vtype_val ;
747+ emit_pre_pop_reg_reg (emit , & vtype_base , REG_ARG_1 , & vtype_val , REG_ARG_3 ); // arg1 = base, arg3 = value
748+ assert (vtype_base == VTYPE_PYOBJ );
749+ assert (vtype_val == VTYPE_PYOBJ );
750+ emit_call_with_imm_arg (emit , RT_F_STORE_ATTR , rt_store_attr , qstr , REG_ARG_2 ); // arg2 = attribute name
751+ emit_post (emit );
732752}
733753
734754static void emit_native_store_subscr (emit_t * emit ) {
@@ -1069,7 +1089,9 @@ static void emit_native_call_method(emit_t *emit, int n_positional, int n_keywor
10691089 assert (vtype_arg1 == VTYPE_PYOBJ );
10701090 emit_call (emit , RT_F_CALL_METHOD_2 , rt_call_method_2 );
10711091 } else {
1072- assert (0 );
1092+ emit_pre (emit );
1093+ emit_get_stack_pointer_to_reg_for_pop (emit , REG_ARG_2 , n_positional + 2 ); // pointer to items in reverse order, including meth and self
1094+ emit_call_with_imm_arg (emit , RT_F_CALL_METHOD_N , rt_call_method_n , n_positional , REG_ARG_1 );
10731095 }
10741096 emit_post_push_reg (emit , VTYPE_PYOBJ , REG_RET );
10751097}
0 commit comments