Skip to content

Commit dbd1955

Browse files
committed
Revert "[Mono] Fix support for nested structs with explicit layout (#61467)"
This reverts commit 64d1276.
1 parent 70d20f1 commit dbd1955

File tree

13 files changed

+21
-532
lines changed

13 files changed

+21
-532
lines changed

src/mono/mono/metadata/class-init.c

Lines changed: 21 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,85 +1864,6 @@ mono_class_is_gparam_with_nonblittable_parent (MonoClass *klass)
18641864
return parent_class != mono_defaults.object_class;
18651865
}
18661866

1867-
/**
1868-
* Checks if there are any overlapping object and non-object fields.
1869-
* The alignment of object reference fields is checked elswhere and this function assumes
1870-
* that all references are aligned correctly.
1871-
*
1872-
* \param layout_check A buffer to check which bytes hold object references or values
1873-
* \param klass Checked struct
1874-
* \param field_offsets Offsets of the klass' fields relative to the start of layout_check
1875-
* \param field_count Count of klass fields
1876-
* \param invalid_field_offset When the layout is invalid it will be set to the offset of the field which is invalid
1877-
*
1878-
* \return True if the layout of the struct is valid, otherwise false.
1879-
*/
1880-
static gboolean
1881-
validate_struct_fields_overlaps (guint8 *layout_check, int layout_size, MonoClass *klass, const int *field_offsets, const int field_count, int *invalid_field_offset)
1882-
{
1883-
MonoClassField *field;
1884-
MonoType *ftype;
1885-
int field_offset;
1886-
1887-
for (int i = 0; i < field_count && !mono_class_has_failure (klass); i++) {
1888-
// using mono_class_get_fields_internal isn't appropriate here because it will
1889-
// try to call mono_class_setup_fields which is what we're doing already
1890-
field = &m_class_get_fields (klass) [i];
1891-
field_offset = field_offsets [i];
1892-
1893-
if (!field)
1894-
continue;
1895-
if (mono_field_is_deleted (field))
1896-
continue;
1897-
if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1898-
continue;
1899-
1900-
ftype = mono_type_get_underlying_type (field->type);
1901-
ftype = mono_type_get_basic_type_from_generic (ftype);
1902-
1903-
if (mono_type_is_struct (ftype)) {
1904-
// recursively check the layout of the embedded struct
1905-
MonoClass *embedded_class = mono_class_from_mono_type_internal (ftype);
1906-
g_assert (m_class_is_fields_inited (embedded_class));
1907-
1908-
const int embedded_fields_count = mono_class_get_field_count (embedded_class);
1909-
int *embedded_offsets = g_new0 (int, embedded_fields_count);
1910-
for (int j = 0; j < embedded_fields_count; ++j) {
1911-
embedded_offsets [j] = field_offset + m_class_get_fields (embedded_class) [j].offset - MONO_ABI_SIZEOF (MonoObject);
1912-
}
1913-
1914-
gboolean is_valid = validate_struct_fields_overlaps (layout_check, layout_size, embedded_class, embedded_offsets, embedded_fields_count, invalid_field_offset);
1915-
g_free (embedded_offsets);
1916-
1917-
if (!is_valid) {
1918-
// overwrite whatever was in the invalid_field_offset with the offset of the currently checked field
1919-
// we want to return the outer most invalid field
1920-
*invalid_field_offset = field_offset;
1921-
return FALSE;
1922-
}
1923-
} else {
1924-
int align = 0;
1925-
int size = mono_type_size (field->type, &align);
1926-
guint8 type = type_has_references (klass, ftype) ? 1 : 2;
1927-
1928-
// Mark the bytes used by this fields type based on if it contains references or not.
1929-
// Make sure there are no overlaps between object and non-object fields.
1930-
for (int j = 0; j < size; j++) {
1931-
int checked_byte = field_offset + j;
1932-
g_assert(checked_byte < layout_size);
1933-
1934-
if (layout_check [checked_byte] != 0 && layout_check [checked_byte] != type) {
1935-
*invalid_field_offset = field_offset;
1936-
return FALSE;
1937-
}
1938-
layout_check [checked_byte] = type;
1939-
}
1940-
}
1941-
}
1942-
1943-
return TRUE;
1944-
}
1945-
19461867
/*
19471868
* mono_class_layout_fields:
19481869
* @class: a class
@@ -2233,12 +2154,29 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_
22332154
}
22342155

22352156
/* check for incorrectly aligned or overlapped by a non-object field */
2236-
guint8 *layout_check;
2157+
guint8 *layout_check;
22372158
if (has_references) {
22382159
layout_check = g_new0 (guint8, real_size);
2239-
int invalid_field_offset;
2240-
if (!validate_struct_fields_overlaps (layout_check, real_size, klass, field_offsets, top, &invalid_field_offset)) {
2241-
mono_class_set_type_load_failure (klass, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, invalid_field_offset);
2160+
for (i = 0; i < top && !mono_class_has_failure (klass); i++) {
2161+
field = &klass->fields [i];
2162+
if (!field)
2163+
continue;
2164+
if (mono_field_is_deleted (field))
2165+
continue;
2166+
if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
2167+
continue;
2168+
int align = 0;
2169+
int size = mono_type_size (field->type, &align);
2170+
MonoType *ftype = mono_type_get_underlying_type (field->type);
2171+
ftype = mono_type_get_basic_type_from_generic (ftype);
2172+
guint8 type = type_has_references (klass, ftype) ? 1 : 2;
2173+
for (int j = 0; j < size; j++) {
2174+
if (layout_check [field_offsets [i] + j] != 0 && layout_check [field_offsets [i] + j] != type) {
2175+
mono_class_set_type_load_failure (klass, "Could not load type '%s' because it contains an object field at offset %d that is incorrectly aligned or overlapped by a non-object field.", klass->name, field->offset);
2176+
break;
2177+
}
2178+
layout_check [field_offsets [i] + j] = type;
2179+
}
22422180
}
22432181
g_free (layout_check);
22442182
}

src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.cs

Lines changed: 0 additions & 74 deletions
This file was deleted.

src/tests/Loader/classloader/explicitlayout/NestedStructs/case01.csproj

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.cs

Lines changed: 0 additions & 89 deletions
This file was deleted.

src/tests/Loader/classloader/explicitlayout/NestedStructs/case02.csproj

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.cs

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/tests/Loader/classloader/explicitlayout/NestedStructs/case03.csproj

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)