X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsre.c;h=041a2ba6f4859f38494cd49ea37422e4e4f3a8aa;hb=a713a14521da8ddf992c4a3e64855d56cb7897a3;hp=947f9a416fbb59a7d75362cd184805c0e6860087;hpb=12db41477b0ba2855070fc3d1913cb99fc93d0c0;p=mono.git diff --git a/mono/metadata/sre.c b/mono/metadata/sre.c index 947f9a416fb..041a2ba6f48 100644 --- a/mono/metadata/sre.c +++ b/mono/metadata/sre.c @@ -35,13 +35,6 @@ #include "mono/utils/checked-build.h" #include "mono/utils/mono-digest.h" -void -mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry) -{ - mono_gc_deregister_root ((char*) &entry->gparam); - g_free (entry); -} - static GENERATE_GET_CLASS_WITH_CACHE (marshal_as_attribute, System.Runtime.InteropServices, MarshalAsAttribute); static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, ModuleBuilder); @@ -49,8 +42,10 @@ static GENERATE_GET_CLASS_WITH_CACHE (module_builder, System.Reflection.Emit, Mo static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec); static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error); static gboolean ensure_runtime_vtable (MonoClass *klass, MonoError *error); -static guint32 mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error); static void reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb); +static gboolean reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error); +static gboolean reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error); + static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly); #endif @@ -65,6 +60,7 @@ static gboolean is_sre_type_builder (MonoClass *klass); static gboolean is_sre_method_builder (MonoClass *klass); static gboolean is_sre_field_builder (MonoClass *klass); static gboolean is_sre_gparam_builder (MonoClass *klass); +static gboolean is_sre_enum_builder (MonoClass *klass); static gboolean is_sr_mono_method (MonoClass *klass); static gboolean is_sr_mono_field (MonoClass *klass); @@ -102,7 +98,7 @@ type_get_qualified_name (MonoType *type, MonoAssembly *ass) return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION); ta = klass->image->assembly; if (assembly_is_dynamic (ta) || (ta == ass)) { - if (klass->generic_class || klass->generic_container) + if (mono_class_is_ginst (klass) || mono_class_is_gtd (klass)) /* For generic type definitions, we want T, while REFLECTION returns T */ return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME); else @@ -361,7 +357,6 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs) } #endif - guint32 mono_reflection_resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image) { @@ -682,52 +677,6 @@ mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, return token; } -static guint32 -mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method, MonoError *error) -{ - guint32 token, parent, sig; - ReflectionMethodBuilder rmb; - MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type; - - mono_error_init (error); - token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method)); - if (token) - return token; - - if (!mono_reflection_methodbuilder_from_method_builder (&rmb, method, error)) - return 0; - - /* - * A methodref signature can't contain an unmanaged calling convention. - * Since some flags are encoded as part of call_conv, we need to check against it. - */ - if ((rmb.call_conv & ~0x60) != MONO_CALL_DEFAULT && (rmb.call_conv & ~0x60) != MONO_CALL_VARARG) - rmb.call_conv = (rmb.call_conv & 0x60) | MONO_CALL_DEFAULT; - - sig = mono_dynimage_encode_method_builder_signature (assembly, &rmb, error); - return_val_if_nok (error, 0); - - if (tb->generic_params) { - parent = mono_dynimage_encode_generic_typespec (assembly, tb, error); - return_val_if_nok (error, 0); - } else { - MonoType *t = mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type, error); - return_val_if_nok (error, 0); - - parent = mono_image_typedef_or_ref (assembly, t); - } - - char *name = mono_string_to_utf8_checked (method->name, error); - return_val_if_nok (error, 0); - - token = mono_image_add_memberef_row (assembly, parent, name, sig); - g_free (name); - - g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token)); - - return token; -} - static guint32 mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 original, const gchar *name, guint32 sig) @@ -752,54 +701,12 @@ mono_image_get_varargs_method_token (MonoDynamicImage *assembly, guint32 origina return token; } -static guint32 -mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb, MonoError *error) -{ - MonoDynamicTable *table; - guint32 *values; - guint32 token, mtoken = 0; - - mono_error_init (error); - token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->methodspec, mb)); - if (token) - return token; - - table = &assembly->tables [MONO_TABLE_METHODSPEC]; - - mtoken = mono_image_get_methodref_token_for_methodbuilder (assembly, mb, error); - if (!mono_error_ok (error)) - return 0; - - switch (mono_metadata_token_table (mtoken)) { - case MONO_TABLE_MEMBERREF: - mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODREF; - break; - case MONO_TABLE_METHOD: - mtoken = (mono_metadata_token_index (mtoken) << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF; - break; - default: - g_assert_not_reached (); - } - - if (assembly->save) { - alloc_table (table, table->rows + 1); - values = table->values + table->next_idx * MONO_METHODSPEC_SIZE; - values [MONO_METHODSPEC_METHOD] = mtoken; - values [MONO_METHODSPEC_SIGNATURE] = mono_dynimage_encode_generic_method_definition_sig (assembly, mb); - } - - token = MONO_TOKEN_METHOD_SPEC | table->next_idx; - table->next_idx ++; - - mono_g_hash_table_insert (assembly->methodspec, mb, GUINT_TO_POINTER(token)); - return token; -} #endif static gboolean is_field_on_inst (MonoClassField *field) { - return field->parent->generic_class && field->parent->generic_class->is_dynamic; + return mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->is_dynamic; } #ifndef DISABLE_REFLECTION_EMIT @@ -816,9 +723,9 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObject *f, MonoCl if (token) return token; - if (field->parent->generic_class && field->parent->generic_class->container_class && field->parent->generic_class->container_class->fields) { + if (mono_class_is_ginst (field->parent) && mono_class_get_generic_class (field->parent)->container_class && mono_class_get_generic_class (field->parent)->container_class->fields) { int index = field - field->parent->fields; - type = mono_field_get_type (&field->parent->generic_class->container_class->fields [index]); + type = mono_field_get_type (&mono_class_get_generic_class (field->parent)->container_class->fields [index]); } else { type = mono_field_get_type (field); } @@ -915,21 +822,6 @@ mono_image_get_inflated_method_token (MonoDynamicImage *assembly, MonoMethod *m) return token; } -void -mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error) -{ - MonoReflectionTypeBuilder *tb; - - mono_error_init (error); - - if (!is_sre_type_builder(mono_object_class (type))) - return; - tb = (MonoReflectionTypeBuilder *)type; - - if (tb && tb->generic_container) - mono_reflection_create_generic_class (tb, error); -} - static guint32 mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper, MonoError *error) { @@ -1243,27 +1135,12 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, return 0; } - if (strcmp (klass->name, "MethodBuilder") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); - } else if (strcmp (klass->name, "ConstructorBuilder") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); - } else if (strcmp (klass->name, "FieldBuilder") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); - } else if (strcmp (klass->name, "TypeBuilder") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); - } else if (strcmp (klass->name, "RuntimeType") == 0) { + if (strcmp (klass->name, "RuntimeType") == 0) { MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj, error); return_val_if_nok (error, 0); MonoClass *mc = mono_class_from_mono_type (type); token = mono_metadata_token_from_dor ( - mono_dynimage_encode_typedef_or_ref_full (assembly, type, mc->generic_container == NULL || create_open_instance)); - } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); + mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance)); } else if (strcmp (klass->name, "MonoCMethod") == 0 || strcmp (klass->name, "MonoMethod") == 0) { MonoReflectionMethod *m = (MonoReflectionMethod *)obj; @@ -1273,7 +1150,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, else token = mono_image_get_inflated_method_token (assembly, m->method); } else if ((m->method->klass->image == &assembly->image) && - !m->method->klass->generic_class) { + !mono_class_is_ginst (m->method->klass)) { static guint32 method_table_idx = 0xffffff; if (m->method->klass->wastypebuilder) { /* we use the same token as the one that was assigned @@ -1317,18 +1194,6 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObject *obj, return_val_if_nok (error, 0); token = mono_metadata_token_from_dor ( mono_image_typedef_or_ref (assembly, type)); - } else if (is_sre_generic_instance (klass) || is_sre_array (klass) || is_sre_byref (klass) || is_sre_pointer (klass)) { - /* These are handled in managed code */ - g_assert_not_reached (); - } else if (strcmp (klass->name, "FieldOnTypeBuilderInst") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); - } else if (strcmp (klass->name, "ConstructorOnTypeBuilderInst") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); - } else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) { - /* These are handled in managed code */ - g_assert_not_reached (); } else { g_error ("requested token for %s\n", klass->name); } @@ -1441,13 +1306,13 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb) static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly) { - CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL); + return CACHE_OBJECT (MonoReflectionAssembly *, assembly, &res->object, NULL); } static gpointer register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module) { - CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL); + return CACHE_OBJECT (MonoReflectionModuleBuilder *, module, &res->module.obj, NULL); } static gboolean @@ -1548,7 +1413,7 @@ is_sre_pointer (MonoClass *klass) static gboolean is_sre_generic_instance (MonoClass *klass) { - check_corlib_type_cached (klass, "System.Reflection", "MonoGenericClass"); + check_corlib_type_cached (klass, "System.Reflection.Emit", "TypeBuilderInstantiation"); } static gboolean @@ -1581,6 +1446,12 @@ is_sre_gparam_builder (MonoClass *klass) check_corlib_type_cached (klass, "System.Reflection.Emit", "GenericTypeParameterBuilder"); } +static gboolean +is_sre_enum_builder (MonoClass *klass) +{ + check_corlib_type_cached (klass, "System.Reflection.Emit", "EnumBuilder"); +} + gboolean mono_is_sre_method_on_tb_inst (MonoClass *klass) { @@ -1678,7 +1549,21 @@ mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error) return NULL; } } - + /* Need to resolve the generic_type in order for it to create its generic context. */ + MonoType *gtd = mono_reflection_type_get_handle (gclass->generic_type, error); + if (!is_ok (error)) { + g_free (types); + return NULL; + } + MonoClass *gtd_klass = mono_class_from_mono_type (gtd); + if (is_sre_type_builder (mono_object_class (gclass->generic_type))) { + reflection_create_generic_class ((MonoReflectionTypeBuilder*)gclass->generic_type, error); + if (!is_ok (error)) { + g_free (types); + return NULL; + } + } + g_assert (count == 0 || mono_class_is_gtd (gtd_klass)); res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types, error); g_free (types); g_assert (res); @@ -1699,11 +1584,23 @@ mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error) param->param.num = gparam->index; if (gparam->mbuilder) { - g_assert (gparam->mbuilder->generic_container); + if (!gparam->mbuilder->generic_container) { + gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer)); + gparam->mbuilder->generic_container->is_method = TRUE; + /* + * Cannot set owner.method, since the MonoMethod is not created yet. + * Set the image field instead, so type_in_image () works. + */ + gparam->mbuilder->generic_container->is_anonymous = TRUE; + gparam->mbuilder->generic_container->owner.image = image; + } param->param.owner = gparam->mbuilder->generic_container; } else if (gparam->tbuilder) { - g_assert (gparam->tbuilder->generic_container); - param->param.owner = gparam->tbuilder->generic_container; + MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)(gparam->tbuilder), error); + mono_error_assert_ok (error); + MonoClass *owner = mono_class_from_mono_type (type); + g_assert (mono_class_is_gtd (owner)); + param->param.owner = mono_class_get_generic_container (owner); } pklass = mono_class_from_generic_parameter_internal ((MonoGenericParam *) param); @@ -1714,6 +1611,18 @@ mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error) mono_image_append_class_to_reflection_info_set (pklass); return &pklass->byval_arg; + } else if (is_sre_enum_builder (klass)) { + MonoReflectionEnumBuilder *ebuilder = (MonoReflectionEnumBuilder *)ref; + + return mono_reflection_type_get_handle ((MonoReflectionType*)ebuilder->tb, error); + } else if (is_sre_type_builder (klass)) { + MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)ref; + + /* This happens when a finished type references an unfinished one. Have to create the minimal type */ + reflection_setup_internal_class (tb, error); + mono_error_assert_ok (error); + g_assert (ref->type); + return ref->type; } g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg)); @@ -1877,12 +1786,6 @@ mono_is_sre_ctor_on_tb_inst (MonoClass *klass) return FALSE; } -void -mono_reflection_init_type_builder_generics (MonoObject *type, MonoError *error) -{ - mono_error_init (error); -} - #endif /* !DISABLE_REFLECTION_EMIT */ @@ -2411,7 +2314,13 @@ reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error return TRUE; } - klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass)); + /* + * The size calculation here warrants some explaining. + * reflection_setup_internal_class is called too early, well before we know whether the type will be a GTD or DEF, + * meaning we need to alloc enough space to morth a def into a gtd. + */ + klass = (MonoClass *)mono_image_alloc0 (&tb->module->dynamic_image->image, MAX (sizeof (MonoClassDef), sizeof (MonoClassGtd))); + klass->class_kind = MONO_CLASS_DEF; klass->image = &tb->module->dynamic_image->image; @@ -2423,7 +2332,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error if (!is_ok (error)) goto failure; klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx; - klass->flags = tb->attrs; + mono_class_set_flags (klass, tb->attrs); mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD); @@ -2479,6 +2388,7 @@ reflection_setup_internal_class (MonoReflectionTypeBuilder *tb, MonoError *error tb->type.type = &klass->byval_arg; if (tb->nesting_type) { + reflection_setup_internal_class ((MonoReflectionTypeBuilder*)tb->nesting_type, error); g_assert (tb->nesting_type->type); MonoType *nesting_type = mono_reflection_type_get_handle (tb->nesting_type, error); if (!is_ok (error)) goto failure; @@ -2498,73 +2408,59 @@ failure: } /** - * ves_icall_TypeBuilder_setup_internal_class: - * @tb: a TypeBuilder object - * - * (icall) - * Creates a MonoClass that represents the TypeBuilder. - * This is a trick that lets us simplify a lot of reflection code - * (and will allow us to support Build and Run assemblies easier). - * - */ -void -ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb) -{ - MonoError error; - (void) reflection_setup_internal_class (tb, &error); - mono_error_set_pending_exception (&error); -} - -/** - * mono_reflection_create_generic_class: + * reflection_create_generic_class: * @tb: a TypeBuilder object * @error: set on error * * Creates the generic class after all generic parameters have been added. * On success returns TRUE, on failure returns FALSE and sets @error. - * */ -gboolean -mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error) +static gboolean +reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error) { - MonoClass *klass; int count, i; mono_error_init (error); + reflection_setup_internal_class (tb, error); + return_val_if_nok (error, FALSE); + klass = mono_class_from_mono_type (tb->type.type); count = tb->generic_params ? mono_array_length (tb->generic_params) : 0; - if (klass->generic_container || (count == 0)) + if (count == 0) return TRUE; - g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass)); + if (mono_class_try_get_generic_container (klass) != NULL) + return TRUE; /* already setup */ + + MonoGenericContainer *generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); - klass->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); + generic_container->owner.klass = klass; + generic_container->type_argc = count; + generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count); - klass->generic_container->owner.klass = klass; - klass->generic_container->type_argc = count; - klass->generic_container->type_params = (MonoGenericParamFull *)mono_image_alloc0 (klass->image, sizeof (MonoGenericParamFull) * count); + klass->class_kind = MONO_CLASS_GTD; + mono_class_set_generic_container (klass, generic_container); - klass->is_generic = 1; for (i = 0; i < count; i++) { MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i); MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, error); return_val_if_nok (error, FALSE); MonoGenericParamFull *param = (MonoGenericParamFull *) param_type->data.generic_param; - klass->generic_container->type_params [i] = *param; + generic_container->type_params [i] = *param; /*Make sure we are a diferent type instance */ - klass->generic_container->type_params [i].param.owner = klass->generic_container; - klass->generic_container->type_params [i].info.pklass = NULL; - klass->generic_container->type_params [i].info.flags = gparam->attrs; + generic_container->type_params [i].param.owner = generic_container; + generic_container->type_params [i].info.pklass = NULL; + generic_container->type_params [i].info.flags = gparam->attrs; - g_assert (klass->generic_container->type_params [i].param.owner); + g_assert (generic_container->type_params [i].param.owner); } - klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->generic_container); + generic_container->context.class_inst = mono_get_shared_generic_inst (generic_container); return TRUE; } @@ -2705,7 +2601,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, image = dynamic ? NULL : klass->image; if (!dynamic) - g_assert (!klass->generic_class); + g_assert (!mono_class_is_ginst (klass)); mono_loader_lock (); @@ -2812,14 +2708,14 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, if (rmb->generic_params) { int count = mono_array_length (rmb->generic_params); - MonoGenericContainer *container = rmb->generic_container; - - g_assert (container); + MonoGenericContainer *container; + container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); + container->is_method = TRUE; + container->is_anonymous = FALSE; container->type_argc = count; container->type_params = image_g_new0 (image, MonoGenericParamFull, count); container->owner.method = m; - container->is_anonymous = FALSE; // Method is now known, container is no longer anonymous m->is_generic = TRUE; mono_method_set_generic_container (m, container); @@ -2831,6 +2727,12 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, mono_error_assert_ok (error); MonoGenericParamFull *param = (MonoGenericParamFull *) gp_type->data.generic_param; container->type_params [i] = *param; + container->type_params [i].param.owner = container; + + gp->type.type->data.generic_param = (MonoGenericParam*)&container->type_params [i]; + + MonoClass *gklass = mono_class_from_mono_type (gp_type); + gklass->wastypebuilder = TRUE; } /* @@ -2850,9 +2752,9 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass, } } - if (klass->generic_container) { - container->parent = klass->generic_container; - container->context.class_inst = klass->generic_container->context.class_inst; + if (mono_class_is_gtd (klass)) { + container->parent = mono_class_get_generic_container (klass); + container->context.class_inst = mono_class_get_generic_container (klass)->context.class_inst; } container->context.method_inst = mono_get_shared_generic_inst (container); } @@ -2962,14 +2864,15 @@ ctorbuilder_to_mono_method (MonoClass *klass, MonoReflectionCtorBuilder* mb, Mon MonoMethodSignature *sig; mono_loader_lock (); + + if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error)) + return NULL; + g_assert (klass->image != NULL); sig = ctor_builder_to_signature (klass->image, mb, error); mono_loader_unlock (); return_val_if_nok (error, NULL); - if (!mono_reflection_methodbuilder_from_ctor_builder (&rmb, mb, error)) - return NULL; - mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error); return_val_if_nok (error, NULL); mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs); @@ -2991,14 +2894,15 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, mono_error_init (error); mono_loader_lock (); + + if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error)) + return NULL; + g_assert (klass->image != NULL); sig = method_builder_to_signature (klass->image, mb, error); mono_loader_unlock (); return_val_if_nok (error, NULL); - if (!mono_reflection_methodbuilder_from_method_builder (&rmb, mb, error)) - return NULL; - mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error); return_val_if_nok (error, NULL); mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs); @@ -3027,7 +2931,7 @@ methodbuilder_to_mono_method (MonoClass *klass, MonoReflectionMethodBuilder* mb, static gboolean fix_partial_generic_class (MonoClass *klass, MonoError *error) { - MonoClass *gklass = klass->generic_class->container_class; + MonoClass *gklass = mono_class_get_generic_class (klass)->container_class; int i; mono_error_init (error); @@ -3036,7 +2940,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error) return TRUE; if (klass->parent != gklass->parent) { - MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, error); + MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &mono_class_get_generic_class (klass)->context, error); if (mono_error_ok (error)) { MonoClass *parent = mono_class_from_mono_type (parent_type); mono_metadata_free_type (parent_type); @@ -3052,14 +2956,16 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error) } } - if (!klass->generic_class->need_sync) + if (!mono_class_get_generic_class (klass)->need_sync) return TRUE; - if (klass->method.count != gklass->method.count) { - klass->method.count = gklass->method.count; - klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1)); + int mcount = mono_class_get_method_count (klass); + int gmcount = mono_class_get_method_count (gklass); + if (mcount != gmcount) { + mono_class_set_method_count (klass, gmcount); + klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * (gmcount + 1)); - for (i = 0; i < klass->method.count; i++) { + for (i = 0; i < gmcount; i++) { klass->methods [i] = mono_class_inflate_generic_method_full_checked ( gklass->methods [i], klass, mono_class_get_context (klass), error); mono_error_assert_ok (error); @@ -3084,11 +2990,13 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error) klass->interfaces_inited = 1; } - if (klass->field.count != gklass->field.count) { - klass->field.count = gklass->field.count; - klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count); + int fcount = mono_class_get_field_count (klass); + int gfcount = mono_class_get_field_count (gklass); + if (fcount != gfcount) { + mono_class_set_field_count (klass, gfcount); + klass->fields = image_g_new0 (klass->image, MonoClassField, gfcount); - for (i = 0; i < klass->field.count; i++) { + for (i = 0; i < gfcount; i++) { klass->fields [i] = gklass->fields [i]; klass->fields [i].parent = klass; klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), error); @@ -3113,7 +3021,7 @@ fix_partial_generic_class (MonoClass *klass, MonoError *error) static gboolean ensure_generic_class_runtime_vtable (MonoClass *klass, MonoError *error) { - MonoClass *gklass = klass->generic_class->container_class; + MonoClass *gklass = mono_class_get_generic_class (klass)->container_class; mono_error_init (error); @@ -3139,7 +3047,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error) mono_error_init (error); - if (!image_is_dynamic (klass->image) || (!tb && !klass->generic_class) || klass->wastypebuilder) + if (!image_is_dynamic (klass->image) || (!tb && !mono_class_is_ginst (klass)) || klass->wastypebuilder) return TRUE; if (klass->parent) if (!ensure_runtime_vtable (klass->parent, error)) @@ -3148,7 +3056,7 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error) if (tb) { num = tb->ctors? mono_array_length (tb->ctors): 0; num += tb->num_methods; - klass->method.count = num; + mono_class_set_method_count (klass, num); klass->methods = (MonoMethod **)mono_image_alloc (klass->image, sizeof (MonoMethod*) * num); num = tb->ctors? mono_array_length (tb->ctors): 0; for (i = 0; i < num; ++i) { @@ -3178,16 +3086,17 @@ ensure_runtime_vtable (MonoClass *klass, MonoError *error) } klass->interfaces_inited = 1; } - } else if (klass->generic_class){ + } else if (mono_class_is_ginst (klass)){ if (!ensure_generic_class_runtime_vtable (klass, error)) { - mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); + mono_class_set_type_load_failure (klass, "Could not initialize vtable for generic class due to: %s", mono_error_get_message (error)); return FALSE; } } - if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) { + if (mono_class_is_interface (klass) && !mono_class_is_ginst (klass)) { int slot_num = 0; - for (i = 0; i < klass->method.count; ++i) { + int mcount = mono_class_get_method_count (klass); + for (i = 0; i < mcount; ++i) { MonoMethod *im = klass->methods [i]; if (!(im->flags & METHOD_ATTRIBUTE_STATIC)) im->slot = slot_num++; @@ -3294,40 +3203,40 @@ mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides *num_overrides = onum; } +/* This initializes the same data as mono_class_setup_fields () */ static void typebuilder_setup_fields (MonoClass *klass, MonoError *error) { MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mono_class_get_ref_info (klass); MonoReflectionFieldBuilder *fb; MonoClassField *field; + MonoFieldDefaultValue *def_values; MonoImage *image = klass->image; const char *p, *p2; - int i; - guint32 len, idx, real_size = 0; + int i, instance_size, packing_size = 0; + guint32 len, idx; - klass->field.count = tb->num_fields; - klass->field.first = 0; + if (klass->parent) { + if (!klass->parent->size_inited) + mono_class_init (klass->parent); + instance_size = klass->parent->instance_size; + } else { + instance_size = sizeof (MonoObject); + } + + int fcount = tb->num_fields; + mono_class_set_field_count (klass, fcount); mono_error_init (error); if (tb->class_size) { - if ((tb->packing_size & 0xffffff00) != 0) { - char *err_msg = mono_image_strdup_printf (klass->image, "Could not load struct '%s' with packing size %d >= 256", klass->name, tb->packing_size); - mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, err_msg); - return; - } - klass->packing_size = tb->packing_size; - real_size = klass->instance_size + tb->class_size; - } - - if (!klass->field.count) { - klass->instance_size = MAX (klass->instance_size, real_size); - return; + packing_size = tb->packing_size; + instance_size += tb->class_size; } - klass->fields = image_g_new0 (image, MonoClassField, klass->field.count); - mono_class_alloc_ext (klass); - klass->ext->field_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->field.count); + klass->fields = image_g_new0 (image, MonoClassField, fcount); + def_values = image_g_new0 (image, MonoFieldDefaultValue, fcount); + mono_class_set_field_def_values (klass, def_values); /* This is, guess what, a hack. The issue is that the runtime doesn't know how to setup the fields of a typebuider and crash. @@ -3337,10 +3246,11 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) */ klass->size_inited = 1; - for (i = 0; i < klass->field.count; ++i) { + for (i = 0; i < fcount; ++i) { MonoArray *rva_data; fb = (MonoReflectionFieldBuilder *)mono_array_get (tb->fields, gpointer, i); field = &klass->fields [i]; + field->parent = klass; field->name = mono_string_to_utf8_image (image, fb->name, error); if (!mono_error_ok (error)) return; @@ -3359,32 +3269,27 @@ typebuilder_setup_fields (MonoClass *klass, MonoError *error) size_t size = mono_array_length (rva_data); char *data = (char *)mono_image_alloc (klass->image, size); memcpy (data, base, size); - klass->ext->field_def_values [i].data = data; + def_values [i].data = data; } if (fb->offset != -1) field->offset = fb->offset; - field->parent = klass; fb->handle = field; mono_save_custom_attrs (klass->image, field, fb->cattrs); - if (klass->enumtype && !(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) { - klass->cast_class = klass->element_class = mono_class_from_mono_type (field->type); - } 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, &klass->ext->field_def_values [i].def_type); + 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; - klass->ext->field_def_values [i].data = (const char *)mono_image_alloc (image, len); - memcpy ((gpointer)klass->ext->field_def_values [i].data, p, len); + def_values [i].data = (const char *)mono_image_alloc (image, len); + memcpy ((gpointer)def_values [i].data, p, len); } } - klass->instance_size = MAX (klass->instance_size, real_size); - mono_class_layout_fields (klass, klass->instance_size); + mono_class_layout_fields (klass, instance_size, packing_size, TRUE); } static void @@ -3394,19 +3299,23 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error) MonoReflectionPropertyBuilder *pb; MonoImage *image = klass->image; MonoProperty *properties; + MonoClassPropertyInfo *info; int i; mono_error_init (error); - if (!klass->ext) - klass->ext = image_g_new0 (image, MonoClassExt, 1); + info = mono_class_get_property_info (klass); + if (!info) { + info = mono_class_alloc0 (klass, sizeof (MonoClassPropertyInfo)); + mono_class_set_property_info (klass, info); + } - klass->ext->property.count = tb->properties ? mono_array_length (tb->properties) : 0; - klass->ext->property.first = 0; + info->count = tb->properties ? mono_array_length (tb->properties) : 0; + info->first = 0; - properties = image_g_new0 (image, MonoProperty, klass->ext->property.count); - klass->ext->properties = properties; - for (i = 0; i < klass->ext->property.count; ++i) { + properties = image_g_new0 (image, MonoProperty, info->count); + info->properties = properties; + for (i = 0; i < info->count; ++i) { pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i); properties [i].parent = klass; properties [i].attrs = pb->attrs; @@ -3423,16 +3332,16 @@ typebuilder_setup_properties (MonoClass *klass, MonoError *error) guint32 len, idx; const char *p, *p2; MonoDynamicImage *assembly = (MonoDynamicImage*)klass->image; - if (!klass->ext->prop_def_values) - klass->ext->prop_def_values = image_g_new0 (image, MonoFieldDefaultValue, klass->ext->property.count); + if (!info->def_values) + info->def_values = image_g_new0 (image, MonoFieldDefaultValue, info->count); properties [i].attrs |= PROPERTY_ATTRIBUTE_HAS_DEFAULT; - idx = mono_dynimage_encode_constant (assembly, pb->def_value, &klass->ext->prop_def_values [i].def_type); + idx = mono_dynimage_encode_constant (assembly, pb->def_value, &info->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; - klass->ext->prop_def_values [i].data = (const char *)mono_image_alloc (image, len); - memcpy ((gpointer)klass->ext->prop_def_values [i].data, p, len); + info->def_values [i].data = (const char *)mono_image_alloc (image, len); + memcpy ((gpointer)info->def_values [i].data, p, len); } } } @@ -3444,19 +3353,20 @@ typebuilder_setup_events (MonoClass *klass, MonoError *error) MonoReflectionEventBuilder *eb; MonoImage *image = klass->image; MonoEvent *events; + MonoClassEventInfo *info; int i; mono_error_init (error); - if (!klass->ext) - klass->ext = image_g_new0 (image, MonoClassExt, 1); + info = mono_class_alloc0 (klass, sizeof (MonoClassEventInfo)); + mono_class_set_event_info (klass, info); - klass->ext->event.count = tb->events ? mono_array_length (tb->events) : 0; - klass->ext->event.first = 0; + info->count = tb->events ? mono_array_length (tb->events) : 0; + info->first = 0; - events = image_g_new0 (image, MonoEvent, klass->ext->event.count); - klass->ext->events = events; - for (i = 0; i < klass->ext->event.count; ++i) { + events = image_g_new0 (image, MonoEvent, info->count); + info->events = events; + for (i = 0; i < info->count; ++i) { eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i); events [i].parent = klass; events [i].attrs = eb->attrs; @@ -3508,7 +3418,7 @@ remove_instantiations_of_and_ensure_contents (gpointer key, MonoClass *inst_klass = mono_class_from_mono_type (type); //Ensure it's safe to use it. if (!fix_partial_generic_class (inst_klass, error)) { - mono_class_set_failure (inst_klass, MONO_EXCEPTION_TYPE_LOAD, NULL); + mono_class_set_type_load_failure (inst_klass, "Could not initialized generic type instance due to: %s", mono_error_get_message (error)); // Marked the class with failure, but since some other instantiation already failed, // just report that one, and swallow the error from this one. if (already_failed) @@ -3530,6 +3440,9 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) mono_error_init (&error); + reflection_create_generic_class (tb, &error); + mono_error_assert_ok (&error); + domain = mono_object_domain (tb); klass = mono_class_from_mono_type (tb->type.type); @@ -3554,7 +3467,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) * Fields to set in klass: * the various flags: delegate/unicode/contextbound etc. */ - klass->flags = tb->attrs; + mono_class_set_flags (klass, tb->attrs); klass->has_cctor = 1; mono_class_setup_parent (klass, klass->parent); @@ -3569,34 +3482,24 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) goto failure; if (tb->subtypes) { + GList *nested = NULL; for (i = 0; i < mono_array_length (tb->subtypes); ++i) { MonoReflectionTypeBuilder *subtb = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i); - mono_class_alloc_ext (klass); + + if (!subtb->type.type) { + reflection_setup_internal_class (subtb, &error); + mono_error_assert_ok (&error); + } + MonoType *subtype = mono_reflection_type_get_handle ((MonoReflectionType*)subtb, &error); if (!is_ok (&error)) goto failure; - klass->ext->nested_classes = g_list_prepend_image (klass->image, klass->ext->nested_classes, mono_class_from_mono_type (subtype)); + nested = g_list_prepend_image (klass->image, nested, mono_class_from_mono_type (subtype)); } + mono_class_set_nested_classes_property (klass, nested); } klass->nested_classes_inited = TRUE; - /* fields and object layout */ - if (klass->parent) { - if (!klass->parent->size_inited) - mono_class_init (klass->parent); - klass->instance_size = klass->parent->instance_size; - klass->sizes.class_size = 0; - klass->min_align = klass->parent->min_align; - /* if the type has no fields we won't call the field_setup - * routine which sets up klass->has_references. - */ - klass->has_references |= klass->parent->has_references; - } else { - klass->instance_size = sizeof (MonoObject); - klass->min_align = 1; - } - - /* FIXME: handle packing_size and instance_size */ typebuilder_setup_fields (klass, &error); if (!mono_error_ok (&error)) goto failure; @@ -3610,6 +3513,16 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) klass->wastypebuilder = TRUE; + if (tb->generic_params) { + for (i = 0; i < mono_array_length (tb->generic_params); i++) { + MonoReflectionGenericParam *gparam = (MonoReflectionGenericParam *)mono_array_get (tb->generic_params, gpointer, i); + MonoType *param_type = mono_reflection_type_get_handle ((MonoReflectionType*)gparam, &error); + MonoClass *gklass = mono_class_from_mono_type (param_type); + + gklass->wastypebuilder = TRUE; + } + } + /* * If we are a generic TypeBuilder, there might be instantiations in the type cache * which have type System.Reflection.MonoGenericClass, but after the type is created, @@ -3617,7 +3530,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) * * Together with this we must ensure the contents of all instances to match the created type. */ - if (domain->type_hash && klass->generic_container) { + if (domain->type_hash && mono_class_is_gtd (klass)) { struct remove_instantiations_user_data data; data.klass = klass; data.error = &error; @@ -3631,7 +3544,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) mono_loader_unlock (); if (klass->enumtype && !mono_class_is_valid_enum (klass)) { - mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); + mono_class_set_type_load_failure (klass, "Not a valid enumeration"); mono_error_set_type_load_class (&error, klass, "Not a valid enumeration"); goto failure_unlocked; } @@ -3645,7 +3558,7 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) return res; failure: - mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL); + mono_class_set_type_load_failure (klass, "TypeBuilder could not create runtime class due to: %s", mono_error_get_message (&error)); klass->wastypebuilder = TRUE; mono_domain_unlock (domain); mono_loader_unlock (); @@ -3654,52 +3567,6 @@ failure_unlocked: return NULL; } -static gboolean -reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam, MonoError *error) -{ - MonoImage *image; - - mono_error_init (error); - - image = &gparam->tbuilder->module->dynamic_image->image; - - if (gparam->mbuilder) { - if (!gparam->mbuilder->generic_container) { - MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->mbuilder->type, error); - return_val_if_nok (error, FALSE); - - MonoClass *klass = mono_class_from_mono_type (tb); - gparam->mbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); - gparam->mbuilder->generic_container->is_method = TRUE; - /* - * Cannot set owner.method, since the MonoMethod is not created yet. - * Set the image field instead, so type_in_image () works. - */ - gparam->mbuilder->generic_container->is_anonymous = TRUE; - gparam->mbuilder->generic_container->owner.image = klass->image; - } - } else if (gparam->tbuilder) { - if (!gparam->tbuilder->generic_container) { - MonoType *tb = mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder, error); - return_val_if_nok (error, FALSE); - MonoClass *klass = mono_class_from_mono_type (tb); - gparam->tbuilder->generic_container = (MonoGenericContainer *)mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer)); - gparam->tbuilder->generic_container->owner.klass = klass; - } - } - - return TRUE; -} - -void -ves_icall_GenericTypeParameterBuilder_initialize (MonoReflectionGenericParam *gparam) -{ - MonoError error; - (void) reflection_initialize_generic_parameter (gparam, &error); - mono_error_set_pending_exception (&error); -} - - typedef struct { MonoMethod *handle; MonoDomain *domain; @@ -3914,8 +3781,8 @@ ensure_complete_type (MonoClass *klass, MonoError *error) //g_assert (klass->wastypebuilder); } - if (klass->generic_class) { - MonoGenericInst *inst = klass->generic_class->context.class_inst; + if (mono_class_is_ginst (klass)) { + MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst; int i; for (i = 0; i < inst->type_argc; ++i) { @@ -4121,19 +3988,6 @@ mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObj return NULL; } -void -ves_icall_TypeBuilder_setup_internal_class (MonoReflectionTypeBuilder *tb) -{ - g_assert_not_reached (); -} - -gboolean -mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb, MonoError *error) -{ - g_assert_not_reached (); - return FALSE; -} - void mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb) { @@ -4183,12 +4037,6 @@ ves_icall_TypeBuilder_create_runtime_class (MonoReflectionTypeBuilder *tb) return NULL; } -void -ves_icall_GenericTypeParameterBuilder_initialize_generic_parameter (MonoReflectionGenericParam *gparam) -{ - g_assert_not_reached (); -} - void ves_icall_DynamicMethod_create_dynamic_method (MonoReflectionDynamicMethod *mb) { @@ -4205,27 +4053,12 @@ mono_reflection_type_get_handle (MonoReflectionType* ref, MonoError *error) #endif /* DISABLE_REFLECTION_EMIT */ -#ifndef DISABLE_REFLECTION_EMIT -MonoMethod* -mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error) -{ - MonoType *tb; - MonoClass *klass; - - tb = mono_reflection_type_get_handle ((MonoReflectionType*)mb->type, error); - return_val_if_nok (error, NULL); - klass = mono_class_from_mono_type (tb); - - return methodbuilder_to_mono_method (klass, mb, error); -} -#else /* DISABLE_REFLECTION_EMIT */ -MonoMethod* -mono_reflection_method_builder_to_mono_method (MonoReflectionMethodBuilder *mb, MonoError *error) +void +mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry) { - g_assert_not_reached (); - return NULL; + mono_gc_deregister_root ((char*) &entry->gparam); + g_free (entry); } -#endif /* DISABLE_REFLECTION_EMIT */ gint32 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, gboolean create_open_instance) @@ -4286,21 +4119,6 @@ ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, gui return obj; } -/** - * ves_icall_TypeBuilder_create_generic_class: - * @tb: a TypeBuilder object - * - * (icall) - * Creates the generic class after all generic parameters have been added. - */ -void -ves_icall_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb) -{ - MonoError error; - (void) mono_reflection_create_generic_class (tb, &error); - mono_error_set_pending_exception (&error); -} - #ifndef DISABLE_REFLECTION_EMIT MonoArray* ves_icall_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)