[Mono-devel-list] Re: [PATCH] CAS support for reflection with [Link|Inheritance]Demand

Paolo Molaro lupus at ximian.com
Wed Mar 9 14:05:13 EST 2005


On 03/04/05 Sebastien Pouliot wrote:
> +MonoBoolean
> +ves_icall_System_MonoType_InternalReflectedLinkDemand (MonoReflectionMethod *m)
> +{
> +	MonoDeclSecurityActions kactions;
> +	MonoDeclSecurityActions mactions;
> +
> +	MONO_ARCH_SAVE_REGS;
> +
> +	if (mono_secman_reflectedlinkdemand (m, &kactions, &mactions)) {
> +		MonoAssembly *assembly = mono_image_get_assembly (m->method->klass->image);
> +		MonoDomain *domain = mono_domain_get ();
> +		MonoReflectionAssembly *refass = mono_assembly_get_object (domain, assembly);
> +		MonoSecurityManager *secman = mono_security_manager_get_methods ();
> +		MonoObject *res;
> +		gpointer args [3];
> +
> +		args [0] = refass;
> +		args [1] = &kactions;
> +		args [2] = &mactions;
> +
> +		res = mono_runtime_invoke (secman->linkdemand, NULL, args, NULL);
> +		return !(*(MonoBoolean *) mono_object_unbox(res));
> +	}

We should avoid code like this that causes managed->unamanged->managed transitions
all the time. It should be implemented with exposing mono_secman_reflectedlinkdemand
as an icall and then calling secman->linkdemand from managed code with a simple
straight call. This way we avoid some of the transition costs but we
also reduce exception handling complexity. In this case it will also reduce the
number of icalls introduced.

> --- exception.c	(revision 41401)
> +++ exception.c	(working copy)
> @@ -410,3 +410,33 @@
>  {
>  	return mono_exception_from_name (mono_get_corlib (), "System", "StackOverflowException");	
>  }
> +
> +MonoException *
> +mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions)
> +{
> +	MonoClass *klass;
> +	gpointer args [2];
> +	MonoObject *exc;
> +	MonoMethod *method;
> +	gpointer iter;
> +
> +	klass = mono_class_from_name (mono_get_corlib (), "System.Reflection", "ReflectionTypeLoadException");
> +	g_assert (klass);
> +	mono_class_init (klass);
> +
> +	iter = NULL;
> +	while ((method = mono_class_get_methods (klass, &iter))) {
> +		if (!strcmp (".ctor", mono_method_get_name (method)) && mono_method_signature (method)->param_count == 2)
> +			break;
> +		method = NULL;
> +	}

Use the helper function mono_class_get_method_from_name () instead of searching by hand.

> ===================================================================
> --- icall.c	(revision 41402)
> +++ icall.c	(working copy)
> @@ -4179,7 +4191,47 @@
>  				}
>  			}
>  		}
> -	}		
> +	}
> +
> +	if (mono_is_security_manager_active ()) {
> +		/* the ReflectionTypeLoadException must have all the types (Types property), 
> +		 * NULL replacing types which throws an exception. The LoaderException must
> +		 * contains all exceptions for NULL items.
> +		 */
> +
> +		guint32 len = mono_array_length (res);
> +		GList *list = NULL;
> +
> +		for (i = 0; i < len; i++) {
> +			MonoReflectionType *t = mono_array_get (res, gpointer, i);
> +			if (t->type->type == MONO_TYPE_CLASS) {

What is this check for? It's not needed.

> +				MonoClass *klass = mono_type_get_class (t->type);
> +				if ((klass != NULL) && klass->exception_type) {
> +					/* get the exception */
> +					list = g_list_append (list, mono_class_get_exception_for_failure (klass));

You can't add an object to a GList: it can get garbage collected anytime.

lupus

-- 
-----------------------------------------------------------------
lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better



More information about the Mono-devel-list mailing list