@@ -2178,6 +2178,8 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
21782178
21792179 MonoType * tfrom = ctx -> method_inst -> type_argv [0 ];
21802180 MonoType * tto = ctx -> method_inst -> type_argv [1 ];
2181+ tfrom = mini_get_underlying_type (tfrom );
2182+ tto = mini_get_underlying_type (tto );
21812183
21822184 // The underlying API always throws for reference type inputs, so we
21832185 // fallback to the managed implementation to let that handling occur
@@ -2186,18 +2188,8 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
21862188 return FALSE;
21872189 }
21882190
2189- // We also always throw for Nullable<T> inputs, so fallback to the
2190- // managed implementation here as well.
2191-
21922191 MonoClass * tfrom_klass = mono_class_from_mono_type_internal (tfrom );
2193- if (mono_class_is_nullable (tfrom_klass )) {
2194- return FALSE;
2195- }
2196-
21972192 MonoClass * tto_klass = mono_class_from_mono_type_internal (tto );
2198- if (mono_class_is_nullable (tto_klass )) {
2199- return FALSE;
2200- }
22012193
22022194 // The same applies for when the type sizes do not match, as this will always throw
22032195 // and so its not an expected case and we can fallback to the managed implementation
@@ -2215,24 +2207,28 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
22152207 // back to what is effectively `ReadUnaligned<TTo>(ref As<TFrom, byte>(ref source))`
22162208 // for anything that can't be special cased as potentially zero-cost move.
22172209
2210+ #if false
22182211 bool tfrom_is_primitive_or_enum = m_class_is_primitive (tfrom_klass ) || m_class_is_enumtype (tfrom_klass );
22192212 bool tto_is_primitive_or_enum = m_class_is_primitive (tto_klass ) || m_class_is_enumtype (tto_klass );
22202213
2214+ * op = -1 ;
2215+
22212216 if (tfrom_is_primitive_or_enum && tto_is_primitive_or_enum ) {
22222217 * op = interp_get_mov_for_type (mono_mint_type (tto ), TRUE);
22232218 }
22242219
22252220 if (* op == -1 ) {
2226-
2227- if (size <= 4 ) {
2228- * op = MINT_MOV_4 ;
2229- } else if (size <= 8 ) {
2230- * op = MINT_MOV_8 ;
2231- } else {
2232- * op = MINT_MOV_VT ;
2233- }
2221+ return FALSE;
22342222 }
2235-
2223+ #else
2224+ if (size <= 4 ) {
2225+ * op = MINT_MOV_4 ;
2226+ } else if (size <= 8 ) {
2227+ * op = MINT_MOV_8 ;
2228+ } else {
2229+ * op = MINT_MOV_VT ;
2230+ }
2231+ #endif
22362232 if (* op == MINT_MOV_VT ) {
22372233 td -> sp -- ;
22382234 interp_add_ins (td , MINT_MOV_VT );
@@ -2241,8 +2237,16 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
22412237 interp_ins_set_dreg (td -> last_ins , td -> sp [-1 ].var );
22422238 td -> last_ins -> data [0 ] = GINT32_TO_UINT16 (size );
22432239 td -> ip += 5 ;
2244- return TRUE;
2240+
2241+ } else {
2242+ td -> sp -- ;
2243+ interp_add_ins (td , * op );
2244+ interp_ins_set_sreg (td -> last_ins , td -> sp [-1 ].var );
2245+ push_type (td , tto , tto_klass );
2246+ interp_ins_set_dreg (td -> last_ins , td -> sp [-1 ].var );
2247+ td -> ip += 5 ;
22452248 }
2249+ return TRUE;
22462250 } else if (!strcmp (tm , "ByteOffset ")) {
22472251#if SIZEOF_VOID_P == 4
22482252 interp_add_ins (td , MINT_SUB_I4 );
0 commit comments