@@ -1456,25 +1456,27 @@ dump_interp_compacted_ins (const guint16 *ip, const guint16 *start)
14561456{
14571457 int opcode = * ip ;
14581458 int ins_offset = ip - start ;
1459+ GString * str = g_string_new ("" );
14591460
1460- g_print ( "IR_%04x: %-14s" , ins_offset , mono_interp_opname (opcode ));
1461+ g_string_append_printf ( str , "IR_%04x: %-14s" , ins_offset , mono_interp_opname (opcode ));
14611462 ip ++ ;
14621463
14631464 if (mono_interp_op_dregs [opcode ] > 0 )
1464- g_print ( " [%d <-" , * ip ++ );
1465+ g_string_append_printf ( str , " [%d <-" , * ip ++ );
14651466 else
1466- g_print ( " [nil <-" );
1467+ g_string_append_printf ( str , " [nil <-" );
14671468
14681469 if (mono_interp_op_sregs [opcode ] > 0 ) {
14691470 for (int i = 0 ; i < mono_interp_op_sregs [opcode ]; i ++ )
1470- g_print ( " %d" , * ip ++ );
1471- g_print ( "]," );
1471+ g_string_append_printf ( str , " %d" , * ip ++ );
1472+ g_string_append_printf ( str , "]," );
14721473 } else {
1473- g_print ( " nil]," );
1474+ g_string_append_printf ( str , " nil]," );
14741475 }
1475- char * ins = dump_interp_ins_data (NULL , ins_offset , ip , opcode );
1476- g_print ("%s\n" , ins );
1477- g_free (ins );
1476+ char * ins_data = dump_interp_ins_data (NULL , ins_offset , ip , opcode );
1477+ g_print ("%s%s\n" , str -> str , ins_data );
1478+ g_string_free (str , TRUE);
1479+ g_free (ins_data );
14781480}
14791481
14801482static void
@@ -1488,51 +1490,47 @@ dump_interp_code (const guint16 *start, const guint16* end)
14881490}
14891491
14901492static void
1491- dump_interp_inst_no_newline (InterpInst * ins )
1493+ dump_interp_inst (InterpInst * ins )
14921494{
14931495 int opcode = ins -> opcode ;
1494- g_print ("IL_%04x: %-14s" , ins -> il_offset , mono_interp_opname (opcode ));
1496+ GString * str = g_string_new ("" );
1497+ g_string_append_printf (str , "IL_%04x: %-14s" , ins -> il_offset , mono_interp_opname (opcode ));
14951498
14961499 if (mono_interp_op_dregs [opcode ] > 0 )
1497- g_print ( " [%d <-" , ins -> dreg );
1500+ g_string_append_printf ( str , " [%d <-" , ins -> dreg );
14981501 else
1499- g_print ( " [nil <-" );
1502+ g_string_append_printf ( str , " [nil <-" );
15001503
15011504 if (mono_interp_op_sregs [opcode ] > 0 ) {
15021505 for (int i = 0 ; i < mono_interp_op_sregs [opcode ]; i ++ ) {
15031506 if (ins -> sregs [i ] == MINT_CALL_ARGS_SREG ) {
1504- g_print ( " c:" );
1507+ g_string_append_printf ( str , " c:" );
15051508 int * call_args = ins -> info .call_args ;
15061509 if (call_args ) {
15071510 while (* call_args != -1 ) {
1508- g_print ( " %d" , * call_args );
1511+ g_string_append_printf ( str , " %d" , * call_args );
15091512 call_args ++ ;
15101513 }
15111514 }
15121515 } else {
1513- g_print ( " %d" , ins -> sregs [i ]);
1516+ g_string_append_printf ( str , " %d" , ins -> sregs [i ]);
15141517 }
15151518 }
1516- g_print ( "]," );
1519+ g_string_append_printf ( str , "]," );
15171520 } else {
1518- g_print ( " nil]," );
1521+ g_string_append_printf ( str , " nil]," );
15191522 }
15201523
15211524 if (opcode == MINT_LDLOCA_S ) {
15221525 // LDLOCA has special semantics, it has data in sregs [0], but it doesn't have any sregs
1523- g_print ( " %d" , ins -> sregs [0 ]);
1526+ g_string_append_printf ( str , " %d" , ins -> sregs [0 ]);
15241527 } else {
15251528 char * descr = dump_interp_ins_data (ins , ins -> il_offset , & ins -> data [0 ], ins -> opcode );
1526- g_print ( "%s" , descr );
1529+ g_string_append_printf ( str , "%s" , descr );
15271530 g_free (descr );
15281531 }
1529- }
1530-
1531- static void
1532- dump_interp_inst (InterpInst * ins )
1533- {
1534- dump_interp_inst_no_newline (ins );
1535- g_print ("\n" );
1532+ g_print ("%s\n" , str -> str );
1533+ g_string_free (str , TRUE);
15361534}
15371535
15381536static G_GNUC_UNUSED void
@@ -1591,21 +1589,6 @@ interp_method_get_header (MonoMethod* method, MonoError *error)
15911589 return mono_method_get_header_internal (method , error );
15921590}
15931591
1594- /* stores top of stack as local and pushes address of it on stack */
1595- static void
1596- emit_store_value_as_local (TransformData * td , MonoType * src )
1597- {
1598- int local = create_interp_local (td , mini_native_type_replace_type (src ));
1599-
1600- store_local (td , local );
1601-
1602- interp_add_ins (td , MINT_LDLOCA_S );
1603- push_simple_type (td , STACK_TYPE_MP );
1604- interp_ins_set_dreg (td -> last_ins , td -> sp [-1 ].local );
1605- interp_ins_set_sreg (td -> last_ins , local );
1606- td -> locals [local ].indirects ++ ;
1607- }
1608-
16091592static gboolean
16101593interp_ip_in_cbb (TransformData * td , int il_offset )
16111594{
@@ -1916,37 +1899,33 @@ interp_handle_magic_type_intrinsics (TransformData *td, MonoMethod *target_metho
19161899 int src_size = mini_magic_type_size (NULL , src );
19171900 int dst_size = mini_magic_type_size (NULL , dst );
19181901
1919- gboolean store_value_as_local = FALSE;
1902+ gboolean managed_fallback = FALSE;
19201903
19211904 switch (type_index ) {
19221905 case 0 : case 1 :
19231906 if (!mini_magic_is_int_type (src ) || !mini_magic_is_int_type (dst )) {
19241907 if (mini_magic_is_int_type (src ))
1925- store_value_as_local = TRUE;
1908+ managed_fallback = TRUE;
19261909 else if (mono_class_is_magic_float (src_klass ))
1927- store_value_as_local = TRUE;
1910+ managed_fallback = TRUE;
19281911 else
19291912 return FALSE;
19301913 }
19311914 break ;
19321915 case 2 :
19331916 if (!mini_magic_is_float_type (src ) || !mini_magic_is_float_type (dst )) {
19341917 if (mini_magic_is_float_type (src ))
1935- store_value_as_local = TRUE;
1918+ managed_fallback = TRUE;
19361919 else if (mono_class_is_magic_int (src_klass ))
1937- store_value_as_local = TRUE;
1920+ managed_fallback = TRUE;
19381921 else
19391922 return FALSE;
19401923 }
19411924 break ;
19421925 }
19431926
1944- if (store_value_as_local ) {
1945- emit_store_value_as_local (td , src );
1946-
1947- /* emit call to managed conversion method */
1927+ if (managed_fallback )
19481928 return FALSE;
1949- }
19501929
19511930 if (src_size > dst_size ) { // 8 -> 4
19521931 switch (type_index ) {
@@ -2003,15 +1982,6 @@ interp_handle_magic_type_intrinsics (TransformData *td, MonoMethod *target_metho
20031982 td -> ip += 5 ;
20041983 return TRUE;
20051984 } else if (!strcmp ("CompareTo" , tm ) || !strcmp ("Equals" , tm )) {
2006- MonoType * arg = csignature -> params [0 ];
2007- int mt = mint_type (arg );
2008-
2009- /* on 'System.n*::{CompareTo,Equals} (System.n*)' variant we need to push managed
2010- * pointer instead of value */
2011- if (mt != MINT_TYPE_O )
2012- emit_store_value_as_local (td , arg );
2013-
2014- /* emit call to managed conversion method */
20151985 return FALSE;
20161986 } else if (!strcmp (".cctor" , tm )) {
20171987 return FALSE;
@@ -2848,8 +2818,7 @@ interp_method_check_inlining (TransformData *td, MonoMethod *method, MonoMethodS
28482818 if (method -> wrapper_type != MONO_WRAPPER_NONE )
28492819 return FALSE;
28502820
2851- /* Our usage of `emit_store_value_as_local ()` for nint, nuint and nfloat
2852- * is kinda hacky, and doesn't work with the inliner */
2821+ // FIXME Re-enable this
28532822 if (mono_class_get_magic_index (method -> klass ) >= 0 )
28542823 return FALSE;
28552824
@@ -6036,6 +6005,8 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header,
60366005 td -> sp -- ;
60376006 interp_emit_sfld_access (td , field , field_klass , mt , TRUE, error );
60386007 goto_if_nok (error , exit );
6008+ } 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 ))) {
6009+ // No need to load anything, the value is already on the execution stack
60396010 } else if (td -> sp [-1 ].type == STACK_TYPE_VT ) {
60406011 int size = 0 ;
60416012 /* First we pop the vt object from the stack. Then we push the field */
0 commit comments