[sre] Outline typebuilder_setup_fields loop body (mono/mono#16184)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Tue, 13 Aug 2019 13:31:31 +0000 (09:31 -0400)
committerGitHub <noreply@github.com>
Tue, 13 Aug 2019 13:31:31 +0000 (09:31 -0400)
The loop body uses coop handles, so wrap it in HANDLE_FUNCTION_ENTER/HANDLE_FUNCTION_RETURN

Commit migrated from https://github.com/mono/mono/commit/1f4ac5d767570b5c4c73ce75b6c9c49bfcb5fc56

src/mono/mono/metadata/sre.c

index 782a9b4..0604674 100644 (file)
@@ -3581,18 +3581,77 @@ modulebuilder_get_next_table_index (MonoReflectionModuleBuilder *mb, gint32 tabl
        return index;
 }
 
+static void
+typebuilder_setup_one_field (MonoDynamicImage *dynamic_image, MonoClass *klass, int32_t first_idx, MonoArray *tb_fields, int i, MonoFieldDefaultValue *def_value_out, MonoError *error)
+{
+       HANDLE_FUNCTION_ENTER ();
+       {
+               MonoImage *image = klass->image;
+               MonoReflectionFieldBuilder *fb;
+               MonoClassField *field;
+               MonoArray *rva_data;
+
+               fb = (MonoReflectionFieldBuilder *)mono_array_get_internal (tb_fields, gpointer, i);
+               field = &klass->fields [i];
+               field->parent = klass;
+               field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
+               goto_if_nok (error, leave);
+               if (fb->attrs) {
+                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+                       goto_if_nok (error, leave);
+                       field->type = mono_metadata_type_dup (klass->image, type);
+                       field->type->attrs = fb->attrs;
+               } else {
+                       field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
+                       goto_if_nok (error, leave);
+               }
+
+               if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
+                       mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
+                       goto leave;
+               }
+
+               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
+                       char *base = mono_array_addr_internal (rva_data, char, 0);
+                       size_t size = mono_array_length_internal (rva_data);
+                       char *data = (char *)mono_image_alloc (klass->image, size);
+                       memcpy (data, base, size);
+                       def_value_out->data = data;
+               }
+               if (fb->offset != -1)
+                       field->offset = fb->offset;
+               fb->handle = field;
+               mono_save_custom_attrs (klass->image, field, fb->cattrs);
+
+               if (fb->def_value) {
+                       guint32 len, idx;
+                       const char *p, *p2;
+                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
+                       field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
+                       idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_value_out->def_type);
+                       /* Copy the data from the blob since it might get realloc-ed */
+                       p = assembly->blob.data + idx;
+                       len = mono_metadata_decode_blob_size (p, &p2);
+                       len += p2 - p;
+                       def_value_out->data = (const char *)mono_image_alloc (image, len);
+                       memcpy ((gpointer)def_value_out->data, p, len);
+               }
+
+               MonoObjectHandle field_builder_handle = MONO_HANDLE_CAST (MonoObject, MONO_HANDLE_NEW (MonoReflectionFieldBuilder, fb));
+               mono_dynamic_image_register_token (dynamic_image, mono_metadata_make_token (MONO_TABLE_FIELD, first_idx + i), field_builder_handle, MONO_DYN_IMAGE_TOK_NEW);
+       }
+leave:
+       HANDLE_FUNCTION_RETURN ();
+}
+
 /* This initializes the same data as mono_class_setup_fields () */
 static void
 typebuilder_setup_fields (MonoClass *klass, MonoError *error)
 {
        MonoReflectionTypeBuilder *tb = mono_class_get_ref_info_raw (klass); /* FIXME use handles */
-       MonoReflectionFieldBuilder *fb;
-       MonoClassField *field;
        MonoFieldDefaultValue *def_values;
        MonoImage *image = klass->image;
-       const char *p, *p2;
        int i, instance_size, packing_size = 0;
-       guint32 len, idx;
 
        error_init (error);
 
@@ -3632,54 +3691,9 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error)
        klass->size_inited = 1;
 
        for (i = 0; i < fcount; ++i) {
-               MonoArray *rva_data;
-               fb = (MonoReflectionFieldBuilder *)mono_array_get_internal (tb->fields, gpointer, i);
-               field = &klass->fields [i];
-               field->parent = klass;
-               field->name = string_to_utf8_image_raw (image, fb->name, error); /* FIXME use handles */
-               if (!mono_error_ok (error))
+               typebuilder_setup_one_field (tb->module->dynamic_image, klass, first_idx, tb->fields, i, &def_values[i], error);
+               if (!is_ok (error))
                        return;
-               if (fb->attrs) {
-                       MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-                       return_if_nok (error);
-                       field->type = mono_metadata_type_dup (klass->image, type);
-                       field->type->attrs = fb->attrs;
-               } else {
-                       field->type = mono_reflection_type_get_handle ((MonoReflectionType*)fb->type, error);
-                       return_if_nok (error);
-               }
-
-               if (!klass->enumtype && !mono_type_get_underlying_type (field->type)) {
-                       mono_class_set_type_load_failure (klass, "Field '%s' is an enum type with a bad underlying type", field->name);
-                       continue;
-               }
-
-               if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && (rva_data = fb->rva_data)) {
-                       char *base = mono_array_addr_internal (rva_data, char, 0);
-                       size_t size = mono_array_length_internal (rva_data);
-                       char *data = (char *)mono_image_alloc (klass->image, size);
-                       memcpy (data, base, size);
-                       def_values [i].data = data;
-               }
-               if (fb->offset != -1)
-                       field->offset = fb->offset;
-               fb->handle = field;
-               mono_save_custom_attrs (klass->image, field, fb->cattrs);
-
-               if (fb->def_value) {
-                       MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image;
-                       field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
-                       idx = mono_dynimage_encode_constant (assembly, fb->def_value, &def_values [i].def_type);
-                       /* Copy the data from the blob since it might get realloc-ed */
-                       p = assembly->blob.data + idx;
-                       len = mono_metadata_decode_blob_size (p, &p2);
-                       len += p2 - p;
-                       def_values [i].data = (const char *)mono_image_alloc (image, len);
-                       memcpy ((gpointer)def_values [i].data, p, len);
-               }
-
-               MonoObjectHandle field_builder_handle = MONO_HANDLE_CAST (MonoObject, MONO_HANDLE_NEW (MonoReflectionFieldBuilder, fb));
-               mono_dynamic_image_register_token (tb->module->dynamic_image, mono_metadata_make_token (MONO_TABLE_FIELD, first_idx + i), field_builder_handle, MONO_DYN_IMAGE_TOK_NEW);
        }
 
        if (!mono_class_has_failure (klass))