@@ -1446,25 +1446,27 @@ dump_interp_compacted_ins (const guint16 *ip, const guint16 *start)
14461446{
14471447 int opcode = * ip ;
14481448 int ins_offset = ip - start ;
1449+ GString * str = g_string_new ("" );
14491450
1450- g_print ( "IR_%04x: %-14s" , ins_offset , mono_interp_opname (opcode ));
1451+ g_string_append_printf ( str , "IR_%04x: %-14s" , ins_offset , mono_interp_opname (opcode ));
14511452 ip ++ ;
14521453
14531454 if (mono_interp_op_dregs [opcode ] > 0 )
1454- g_print ( " [%d <-" , * ip ++ );
1455+ g_string_append_printf ( str , " [%d <-" , * ip ++ );
14551456 else
1456- g_print ( " [nil <-" );
1457+ g_string_append_printf ( str , " [nil <-" );
14571458
14581459 if (mono_interp_op_sregs [opcode ] > 0 ) {
14591460 for (int i = 0 ; i < mono_interp_op_sregs [opcode ]; i ++ )
1460- g_print ( " %d" , * ip ++ );
1461- g_print ( "]," );
1461+ g_string_append_printf ( str , " %d" , * ip ++ );
1462+ g_string_append_printf ( str , "]," );
14621463 } else {
1463- g_print ( " nil]," );
1464+ g_string_append_printf ( str , " nil]," );
14641465 }
1465- char * ins = dump_interp_ins_data (NULL , ins_offset , ip , opcode );
1466- g_print ("%s\n" , ins );
1467- g_free (ins );
1466+ char * ins_data = dump_interp_ins_data (NULL , ins_offset , ip , opcode );
1467+ g_print ("%s%s\n" , str -> str , ins_data );
1468+ g_string_free (str , TRUE);
1469+ g_free (ins_data );
14681470}
14691471
14701472static void
@@ -1478,51 +1480,47 @@ dump_interp_code (const guint16 *start, const guint16* end)
14781480}
14791481
14801482static void
1481- dump_interp_inst_no_newline (InterpInst * ins )
1483+ dump_interp_inst (InterpInst * ins )
14821484{
14831485 int opcode = ins -> opcode ;
1484- g_print ("IL_%04x: %-14s" , ins -> il_offset , mono_interp_opname (opcode ));
1486+ GString * str = g_string_new ("" );
1487+ g_string_append_printf (str , "IL_%04x: %-14s" , ins -> il_offset , mono_interp_opname (opcode ));
14851488
14861489 if (mono_interp_op_dregs [opcode ] > 0 )
1487- g_print ( " [%d <-" , ins -> dreg );
1490+ g_string_append_printf ( str , " [%d <-" , ins -> dreg );
14881491 else
1489- g_print ( " [nil <-" );
1492+ g_string_append_printf ( str , " [nil <-" );
14901493
14911494 if (mono_interp_op_sregs [opcode ] > 0 ) {
14921495 for (int i = 0 ; i < mono_interp_op_sregs [opcode ]; i ++ ) {
14931496 if (ins -> sregs [i ] == MINT_CALL_ARGS_SREG ) {
1494- g_print ( " c:" );
1497+ g_string_append_printf ( str , " c:" );
14951498 int * call_args = ins -> info .call_args ;
14961499 if (call_args ) {
14971500 while (* call_args != -1 ) {
1498- g_print ( " %d" , * call_args );
1501+ g_string_append_printf ( str , " %d" , * call_args );
14991502 call_args ++ ;
15001503 }
15011504 }
15021505 } else {
1503- g_print ( " %d" , ins -> sregs [i ]);
1506+ g_string_append_printf ( str , " %d" , ins -> sregs [i ]);
15041507 }
15051508 }
1506- g_print ( "]," );
1509+ g_string_append_printf ( str , "]," );
15071510 } else {
1508- g_print ( " nil]," );
1511+ g_string_append_printf ( str , " nil]," );
15091512 }
15101513
15111514 if (opcode == MINT_LDLOCA_S ) {
15121515 // LDLOCA has special semantics, it has data in sregs [0], but it doesn't have any sregs
1513- g_print ( " %d" , ins -> sregs [0 ]);
1516+ g_string_append_printf ( str , " %d" , ins -> sregs [0 ]);
15141517 } else {
15151518 char * descr = dump_interp_ins_data (ins , ins -> il_offset , & ins -> data [0 ], ins -> opcode );
1516- g_print ( "%s" , descr );
1519+ g_string_append_printf ( str , "%s" , descr );
15171520 g_free (descr );
15181521 }
1519- }
1520-
1521- static void
1522- dump_interp_inst (InterpInst * ins )
1523- {
1524- dump_interp_inst_no_newline (ins );
1525- g_print ("\n" );
1522+ g_print ("%s\n" , str -> str );
1523+ g_string_free (str , TRUE);
15261524}
15271525
15281526static G_GNUC_UNUSED void
@@ -1581,21 +1579,6 @@ interp_method_get_header (MonoMethod* method, MonoError *error)
15811579 return mono_method_get_header_internal (method , error );
15821580}
15831581
1584- /* stores top of stack as local and pushes address of it on stack */
1585- static void
1586- emit_store_value_as_local (TransformData * td , MonoType * src )
1587- {
1588- int local = create_interp_local (td , mini_native_type_replace_type (src ));
1589-
1590- store_local (td , local );
1591-
1592- interp_add_ins (td , MINT_LDLOCA_S );
1593- push_simple_type (td , STACK_TYPE_MP );
1594- interp_ins_set_dreg (td -> last_ins , td -> sp [-1 ].local );
1595- interp_ins_set_sreg (td -> last_ins , local );
1596- td -> locals [local ].indirects ++ ;
1597- }
1598-
15991582static gboolean
16001583interp_ip_in_cbb (TransformData * td , int il_offset )
16011584{
@@ -1906,37 +1889,33 @@ interp_handle_magic_type_intrinsics (TransformData *td, MonoMethod *target_metho
19061889 int src_size = mini_magic_type_size (NULL , src );
19071890 int dst_size = mini_magic_type_size (NULL , dst );
19081891
1909- gboolean store_value_as_local = FALSE;
1892+ gboolean managed_fallback = FALSE;
19101893
19111894 switch (type_index ) {
19121895 case 0 : case 1 :
19131896 if (!mini_magic_is_int_type (src ) || !mini_magic_is_int_type (dst )) {
19141897 if (mini_magic_is_int_type (src ))
1915- store_value_as_local = TRUE;
1898+ managed_fallback = TRUE;
19161899 else if (mono_class_is_magic_float (src_klass ))
1917- store_value_as_local = TRUE;
1900+ managed_fallback = TRUE;
19181901 else
19191902 return FALSE;
19201903 }
19211904 break ;
19221905 case 2 :
19231906 if (!mini_magic_is_float_type (src ) || !mini_magic_is_float_type (dst )) {
19241907 if (mini_magic_is_float_type (src ))
1925- store_value_as_local = TRUE;
1908+ managed_fallback = TRUE;
19261909 else if (mono_class_is_magic_int (src_klass ))
1927- store_value_as_local = TRUE;
1910+ managed_fallback = TRUE;
19281911 else
19291912 return FALSE;
19301913 }
19311914 break ;
19321915 }
19331916
1934- if (store_value_as_local ) {
1935- emit_store_value_as_local (td , src );
1936-
1937- /* emit call to managed conversion method */
1917+ if (managed_fallback )
19381918 return FALSE;
1939- }
19401919
19411920 if (src_size > dst_size ) { // 8 -> 4
19421921 switch (type_index ) {
@@ -1993,15 +1972,6 @@ interp_handle_magic_type_intrinsics (TransformData *td, MonoMethod *target_metho
19931972 td -> ip += 5 ;
19941973 return TRUE;
19951974 } else if (!strcmp ("CompareTo" , tm ) || !strcmp ("Equals" , tm )) {
1996- MonoType * arg = csignature -> params [0 ];
1997- int mt = mint_type (arg );
1998-
1999- /* on 'System.n*::{CompareTo,Equals} (System.n*)' variant we need to push managed
2000- * pointer instead of value */
2001- if (mt != MINT_TYPE_O )
2002- emit_store_value_as_local (td , arg );
2003-
2004- /* emit call to managed conversion method */
20051975 return FALSE;
20061976 } else if (!strcmp (".cctor" , tm )) {
20071977 return FALSE;
@@ -2836,8 +2806,7 @@ interp_method_check_inlining (TransformData *td, MonoMethod *method, MonoMethodS
28362806 if (method -> wrapper_type != MONO_WRAPPER_NONE )
28372807 return FALSE;
28382808
2839- /* Our usage of `emit_store_value_as_local ()` for nint, nuint and nfloat
2840- * is kinda hacky, and doesn't work with the inliner */
2809+ // FIXME Re-enable this
28412810 if (mono_class_get_magic_index (method -> klass ) >= 0 )
28422811 return FALSE;
28432812
@@ -6059,6 +6028,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
60596028 td -> sp -- ;
60606029 interp_emit_sfld_access (td , field , field_klass , mt , TRUE, error );
60616030 goto_if_nok (error , exit );
6031+ } else if (td -> sp [-1 ].type != STACK_TYPE_O && td -> sp [-1 ].type != STACK_TYPE_MP && (mono_class_is_magic_int (klass ) || mono_class_is_magic_float (klass ))) {
6032+ // No need to load anything, the value is already on the execution stack
60626033 } else if (td -> sp [-1 ].type == STACK_TYPE_VT ) {
60636034 int size = 0 ;
60646035 /* First we pop the vt object from the stack. Then we push the field */
0 commit comments