Skip to content

Commit f68166e

Browse files
authored
Merge pull request #1807 from Unity-Technologies/fix-uum-30210
[mono][arm64] Fixed passing/receiving hfa structures with fixed buffers.
2 parents 8a82ab0 + 020c562 commit f68166e

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

mono/metadata/marshal-ilgen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ offset_of_first_nonstatic_field (MonoClass *klass)
169169
return 0;
170170
}
171171

172-
static gboolean
172+
gboolean
173173
get_fixed_buffer_attr (MonoClassField *field, MonoType **out_etype, int *out_len)
174174
{
175175
ERROR_DECL (error);

mono/metadata/marshal-ilgen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@
99
MONO_API void
1010
mono_marshal_ilgen_init (void);
1111

12+
gboolean
13+
get_fixed_buffer_attr (MonoClassField *field, MonoType **out_etype, int *out_len);
14+
1215
#endif

mono/mini/mini-arm64.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <mono/utils/mono-mmap.h>
2929
#include <mono/utils/mono-memory-model.h>
3030
#include <mono/metadata/abi-details.h>
31+
#include <mono/metadata/marshal-ilgen.h>
3132

3233
#include "interp/interp.h"
3334

@@ -1167,7 +1168,7 @@ is_hfa (MonoType *t, int *out_nfields, int *out_esize, int *field_offsets)
11671168
gpointer iter;
11681169
MonoClassField *field;
11691170
MonoType *ftype, *prev_ftype = NULL;
1170-
int i, nfields = 0;
1171+
int nfields = 0;
11711172

11721173
klass = mono_class_from_mono_type_internal (t);
11731174
iter = NULL;
@@ -1181,16 +1182,30 @@ is_hfa (MonoType *t, int *out_nfields, int *out_esize, int *field_offsets)
11811182
int nested_nfields, nested_esize;
11821183
int nested_field_offsets [16];
11831184

1184-
if (!is_hfa (ftype, &nested_nfields, &nested_esize, nested_field_offsets))
1185-
return FALSE;
1185+
MonoType *fixed_etype;
1186+
int fixed_len;
1187+
if (get_fixed_buffer_attr (field, &fixed_etype, &fixed_len)) {
1188+
if (fixed_etype->type != MONO_TYPE_R4 && fixed_etype->type != MONO_TYPE_R8)
1189+
return FALSE;
1190+
if (fixed_len > 16)
1191+
return FALSE;
1192+
nested_nfields = fixed_len;
1193+
nested_esize = fixed_etype->type == MONO_TYPE_R4 ? 4 : 8;
1194+
for (int i = 0; i < nested_nfields; ++i)
1195+
nested_field_offsets [i] = i * nested_esize;
1196+
} else {
1197+
if (!is_hfa (ftype, &nested_nfields, &nested_esize, nested_field_offsets))
1198+
return FALSE;
1199+
}
1200+
11861201
if (nested_esize == 4)
11871202
ftype = m_class_get_byval_arg (mono_defaults.single_class);
11881203
else
11891204
ftype = m_class_get_byval_arg (mono_defaults.double_class);
11901205
if (prev_ftype && prev_ftype->type != ftype->type)
11911206
return FALSE;
11921207
prev_ftype = ftype;
1193-
for (i = 0; i < nested_nfields; ++i) {
1208+
for (int i = 0; i < nested_nfields; ++i) {
11941209
if (nfields + i < 4)
11951210
field_offsets [nfields + i] = field->offset - MONO_ABI_SIZEOF (MonoObject) + nested_field_offsets [i];
11961211
}

0 commit comments

Comments
 (0)