Skip to content

Commit 8361978

Browse files
committed
Add alternate
1 parent eed71a9 commit 8361978

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

src/mono/mono/mini/interp/transform.c

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)