Commit message: Handle invalid instantiation of generic methods.

	* verify.c: Add new function to internal verifier API to check
	method instantiations.

	* reflection.c (mono_reflection_bind_generic_method_parameters):
	Check the instantiation before returning it.

	Fixes #655847
CVE: CVE-2010-4254
CWE: CWE-20
Vulnerability description: Mono, when Moonlight before 2.3.0.1 or 2.99.x before 2.99.0.10 is used, does not properly validate arguments to generic methods, which allows remote attackers to bypass generic constraints, and possibly execute arbitrary code, via a crafted method call.

Project: mono
File: reflection.c

static MonoMethod*
mono_reflection_method_get_handle (MonoObject *method)
{
	MonoClass *class = mono_object_class (method);
	if (is_sr_mono_method (class) || is_sr_mono_generic_method (class)) {
		MonoReflectionMethod *sr_method = (MonoReflectionMethod*)method;
		return sr_method->method;
	}
	if (is_sre_method_builder (class)) {
		MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)method;
		return mb->mhandle;
	}
	if (is_sre_method_on_tb_inst (class)) {
		MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)method;
		MonoMethod *result;
		/*FIXME move this to a proper method and unify with resolve_object*/
		if (m->method_args) {
			result = mono_reflection_method_on_tb_inst_get_handle (m);
		} else {
			MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
			MonoClass *inflated_klass = mono_class_from_mono_type (type);
			MonoMethod *mono_method;

			if (is_sre_method_builder (mono_object_class (m->mb)))
				mono_method = ((MonoReflectionMethodBuilder *)m->mb)->mhandle;
 			else if (is_sr_mono_method (mono_object_class (m->mb)))
				mono_method = ((MonoReflectionMethod *)m->mb)->method;
			else
				g_error ("resolve_object:: can't handle a MTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (m->mb)));

			result = inflate_mono_method (inflated_klass, mono_method, (MonoObject*)m->mb);
		}
		return result;
	}

	g_error ("Can't handle methods of type %s:%s", class->name_space, class->name);
	return NULL;

Project: mono
File: reflection.c

add_exported_type (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly, MonoClass *klass, guint32 parent_index)
{
	MonoDynamicTable *table;
	guint32 *values;
	guint32 scope, scope_idx, impl, current_idx;
	gboolean forwarder = TRUE;
	gpointer iter = NULL;
	MonoClass *nested;

	if (klass->nested_in) {
		impl = (parent_index << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_EXP_TYPE;
		forwarder = FALSE;
	} else {
		scope = resolution_scope_from_image (assembly, klass->image);
		g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF);
		scope_idx = scope >> MONO_RESOLTION_SCOPE_BITS;
		impl = (scope_idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
	}

	table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];

	table->rows++;
	alloc_table (table, table->rows);
	current_idx = table->next_idx;
	values = table->values + current_idx * MONO_EXP_TYPE_SIZE;

	values [MONO_EXP_TYPE_FLAGS] = forwarder ? TYPE_ATTRIBUTE_FORWARDER : 0;
	values [MONO_EXP_TYPE_TYPEDEF] = 0;
	values [MONO_EXP_TYPE_IMPLEMENTATION] = impl;
	values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
	values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);

	table->next_idx++;

	while ((nested = mono_class_get_nested_types (klass, &iter)))
		add_exported_type (assemblyb, assembly, nested, current_idx);
}

Project: mono
File: reflection.c

add_custom_modifiers (MonoDynamicImage *assembly, MonoType *type, MonoArray *modreq, MonoArray *modopt)
{
	int i, count, len, pos;
	MonoType *t;

	count = 0;
	if (modreq)
		count += mono_array_length (modreq);
	if (modopt)
		count += mono_array_length (modopt);

	if (count == 0)
		return mono_metadata_type_dup (NULL, type);

	len = MONO_SIZEOF_TYPE + ((gint32)count) * sizeof (MonoCustomMod);
	t = g_malloc (len);
	memcpy (t, type, MONO_SIZEOF_TYPE);

	t->num_mods = count;
	pos = 0;
	if (modreq) {
		for (i = 0; i < mono_array_length (modreq); ++i) {
			MonoType *mod = mono_type_array_get_and_resolve (modreq, i);
			t->modifiers [pos].required = 1;
			t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
			pos ++;
		}
	}
	if (modopt) {
		for (i = 0; i < mono_array_length (modopt); ++i) {
			MonoType *mod = mono_type_array_get_and_resolve (modopt, i);
			t->modifiers [pos].required = 0;
			t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
			pos ++;
		}
	}

	return t;
}

Project: mono
File: reflection.c

static gboolean
is_sre_pointer (MonoClass *class)
{
	check_corlib_type_cached (class, "System.Reflection.Emit", "PointerType");

Project: mono
File: reflection.c

is_field_on_inst (MonoClassField *field)
{
	return (field->parent->generic_class && field->parent->generic_class->is_dynamic && ((MonoDynamicGenericClass*)field->parent->generic_class)->fields);
}

Project: mono
File: reflection.c

mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob)
{
	void *retval;
	MonoClass *klass;
	MonoObject *object;
	MonoType *basetype = type;

	if (!blob)
		return NULL;
	
	klass = mono_class_from_mono_type (type);
	if (klass->valuetype) {
		object = mono_object_new (domain, klass);
		retval = ((gchar *) object + sizeof (MonoObject));
		if (klass->enumtype)
			basetype = mono_class_enum_basetype (klass);
	} else {
		retval = &object;
	}
			
	if (!mono_get_constant_value_from_blob (domain, basetype->type,  blob, retval))
		return object;
	else
		return NULL;
}

Project: mono
File: reflection.c

static gboolean
remove_instantiations_of_and_ensure_contents (gpointer key,
						  gpointer value,
						  gpointer user_data)
{
	MonoType *type = (MonoType*)key;
	MonoClass *klass = (MonoClass*)user_data;

	if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass)) {
		fix_partial_generic_class (mono_class_from_mono_type (type)); //Ensure it's safe to use it.
		return TRUE;
	} else
		return FALSE;

Project: mono
File: reflection.c

load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end)
{
	int slen, type = t->type;
	MonoClass *tklass = t->data.klass;

handle_enum:
	switch (type) {
	case MONO_TYPE_U1:
	case MONO_TYPE_I1:
	case MONO_TYPE_BOOLEAN: {
		MonoBoolean *bval = g_malloc (sizeof (MonoBoolean));
		*bval = *p;
		*end = p + 1;
		return bval;
	}
	case MONO_TYPE_CHAR:
	case MONO_TYPE_U2:
	case MONO_TYPE_I2: {
		guint16 *val = g_malloc (sizeof (guint16));
		*val = read16 (p);
		*end = p + 2;
		return val;
	}
#if SIZEOF_VOID_P == 4
	case MONO_TYPE_U:
	case MONO_TYPE_I:
#endif
	case MONO_TYPE_R4:
	case MONO_TYPE_U4:
	case MONO_TYPE_I4: {
		guint32 *val = g_malloc (sizeof (guint32));
		*val = read32 (p);
		*end = p + 4;
		return val;
	}
#if SIZEOF_VOID_P == 8
	case MONO_TYPE_U: /* error out instead? this should probably not happen */
	case MONO_TYPE_I:
#endif
	case MONO_TYPE_U8:
	case MONO_TYPE_I8: {
		guint64 *val = g_malloc (sizeof (guint64));
		*val = read64 (p);
		*end = p + 8;
		return val;
	}
	case MONO_TYPE_R8: {
		double *val = g_malloc (sizeof (double));
		readr8 (p, val);
		*end = p + 8;
		return val;
	}
	case MONO_TYPE_VALUETYPE:
		if (t->data.klass->enumtype) {
			type = mono_class_enum_basetype (t->data.klass)->type;
			goto handle_enum;
		} else {
			MonoClass *k =  t->data.klass;
			
			if (mono_is_corlib_image (k->image) && strcmp (k->name_space, "System") == 0 && strcmp (k->name, "DateTime") == 0){
				guint64 *val = g_malloc (sizeof (guint64));
				*val = read64 (p);
				*end = p + 8;
				return val;
			}
		}
		g_error ("generic valutype %s not handled in custom attr value decoding", t->data.klass->name);
		break;
		
	case MONO_TYPE_STRING:
		if (*p == (char)0xFF) {
			*end = p + 1;
			return NULL;
		}
		slen = mono_metadata_decode_value (p, &p);
		*end = p + slen;
		return mono_string_new_len (mono_domain_get (), p, slen);
	case MONO_TYPE_CLASS: {
		char *n;
		MonoType *t;
		if (*p == (char)0xFF) {
			*end = p + 1;
			return NULL;
		}
handle_type:
		slen = mono_metadata_decode_value (p, &p);
		n = g_memdup (p, slen + 1);
		n [slen] = 0;
		t = mono_reflection_type_from_name (n, image);
		if (!t)
			g_warning ("Cannot load type '%s'", n);
		g_free (n);
		*end = p + slen;
		if (t)
			return mono_type_get_object (mono_domain_get (), t);
		else
			return NULL;
	}
	case MONO_TYPE_OBJECT: {
		char subt = *p++;
		MonoObject *obj;
		MonoClass *subc = NULL;
		void *val;

		if (subt == 0x50) {
			goto handle_type;
		} else if (subt == 0x0E) {
			type = MONO_TYPE_STRING;
			goto handle_enum;
		} else if (subt == 0x1D) {
			MonoType simple_type = {{0}};
			int etype = *p;
			p ++;

			if (etype == 0x51)
				/* See Partition II, Appendix B3 */
				etype = MONO_TYPE_OBJECT;
			type = MONO_TYPE_SZARRAY;
			simple_type.type = etype;
			tklass = mono_class_from_mono_type (&simple_type);
			goto handle_enum;
		} else if (subt == 0x55) {
			char *n;
			MonoType *t;
			slen = mono_metadata_decode_value (p, &p);
			n = g_memdup (p, slen + 1);
			n [slen] = 0;
			t = mono_reflection_type_from_name (n, image);
			if (!t)
				g_error ("Cannot load type '%s'", n);
			g_free (n);
			p += slen;
			subc = mono_class_from_mono_type (t);
		} else if (subt >= MONO_TYPE_BOOLEAN && subt <= MONO_TYPE_R8) {
			MonoType simple_type = {{0}};
			simple_type.type = subt;
			subc = mono_class_from_mono_type (&simple_type);
		} else {
			g_error ("Unknown type 0x%02x for object type encoding in custom attr", subt);
		}
		val = load_cattr_value (image, &subc->byval_arg, p, end);
		obj = mono_object_new (mono_domain_get (), subc);
		g_assert (!subc->has_references);
		memcpy ((char*)obj + sizeof (MonoObject), val, mono_class_value_size (subc, NULL));
		g_free (val);
		return obj;
	}
	case MONO_TYPE_SZARRAY: {
		MonoArray *arr;
		guint32 i, alen, basetype;
		alen = read32 (p);
		p += 4;
		if (alen == 0xffffffff) {
			*end = p;
			return NULL;
		}
		arr = mono_array_new (mono_domain_get(), tklass, alen);
		basetype = tklass->byval_arg.type;
		if (basetype == MONO_TYPE_VALUETYPE && tklass->enumtype)
			basetype = mono_class_enum_basetype (tklass)->type;
		switch (basetype)
		{
			case MONO_TYPE_U1:
			case MONO_TYPE_I1:
			case MONO_TYPE_BOOLEAN:
				for (i = 0; i < alen; i++) {
					MonoBoolean val = *p++;
					mono_array_set (arr, MonoBoolean, i, val);
				}
				break;
			case MONO_TYPE_CHAR:
			case MONO_TYPE_U2:
			case MONO_TYPE_I2:
				for (i = 0; i < alen; i++) {
					guint16 val = read16 (p);
					mono_array_set (arr, guint16, i, val);
					p += 2;
				}
				break;
			case MONO_TYPE_R4:
			case MONO_TYPE_U4:
			case MONO_TYPE_I4:
				for (i = 0; i < alen; i++) {
					guint32 val = read32 (p);
					mono_array_set (arr, guint32, i, val);
					p += 4;
				}
				break;
			case MONO_TYPE_R8:
				for (i = 0; i < alen; i++) {
					double val;
					readr8 (p, &val);
					mono_array_set (arr, double, i, val);
					p += 8;
				}
				break;
			case MONO_TYPE_U8:
			case MONO_TYPE_I8:
				for (i = 0; i < alen; i++) {
					guint64 val = read64 (p);
					mono_array_set (arr, guint64, i, val);
					p += 8;
				}
				break;
			case MONO_TYPE_CLASS:
			case MONO_TYPE_OBJECT:
			case MONO_TYPE_STRING:
				for (i = 0; i < alen; i++) {
					MonoObject *item = load_cattr_value (image, &tklass->byval_arg, p, &p);
					mono_array_setref (arr, i, item);
				}
				break;
			default:
				g_error ("Type 0x%02x not handled in custom attr array decoding", basetype);
		}
		*end=p;
		return arr;
	}
	default:
		g_error ("Type 0x%02x not handled in custom attr value decoding", type);
	}
	return NULL;
}

Project: mono
File: verify.c

do_initobj (VerifyContext *ctx, int token)
{
	ILStackDesc *obj;
	MonoType *stack, *type = get_boxable_mono_type (ctx, token, "initobj");
	if (!type)
		return;

	if (!check_underflow (ctx, 1))
		return;

	obj = stack_pop (ctx);

	if (!stack_slot_is_managed_pointer (obj)) 
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid object address for initobj at 0x%04x", ctx->ip_offset));

	if (stack_slot_is_managed_mutability_pointer (obj))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use a readonly pointer with initobj at 0x%04x", ctx->ip_offset));

	stack = mono_type_get_type_byval (obj->type);
	if (MONO_TYPE_IS_REFERENCE (stack)) {
		if (!verify_type_compatibility (ctx, stack, type)) 
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Type token of initobj not compatible with value on stack at 0x%04x", ctx->ip_offset));
		else if (IS_STRICT_MODE (ctx) && !mono_metadata_type_equal (type, stack)) 
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Type token of initobj not compatible with value on stack at 0x%04x", ctx->ip_offset));
	} else if (!verify_type_compatibility (ctx, stack, type)) {
		char *expected_name = mono_type_full_name (type);
		char *stack_name = mono_type_full_name (stack);

		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Initobj %s not compatible with value on stack %s at 0x%04x", expected_name, stack_name, ctx->ip_offset));
		g_free (expected_name);
		g_free (stack_name);
	}
}

Project: mono
File: verify.c

GSList*
mono_method_verify_with_current_settings (MonoMethod *method, gboolean skip_visibility)
{
	/* The verifier was disabled at compile time */
	return NULL;

Project: mono
File: verify.c

do_ldelem (VerifyContext *ctx, int opcode, int token)
{
#define IS_ONE_OF2(T, A, B) (T == A || T == B)
	ILStackDesc *index, *array;
	MonoType *type;
	if (!check_underflow (ctx, 2))
		return;

	if (opcode == CEE_LDELEM) {
		if (!(type = verifier_load_type (ctx, token, "ldelem.any"))) {
			ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Type (0x%08x) not found at 0x%04x", token, ctx->ip_offset));
			return;
		}
	} else {
		type = mono_type_from_opcode (opcode);
	}

	index = stack_pop (ctx);
	array = stack_pop (ctx);

	if (stack_slot_get_type (index) != TYPE_I4 && stack_slot_get_type (index) != TYPE_NATIVE_INT)
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Index type(%s) for ldelem.X is not an int or a native int at 0x%04x", stack_slot_get_name (index), ctx->ip_offset));

	if (!stack_slot_is_null_literal (array)) {
		if (stack_slot_get_type (array) != TYPE_COMPLEX || array->type->type != MONO_TYPE_SZARRAY)
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid array type(%s) for ldelem.X at 0x%04x", stack_slot_get_name (array), ctx->ip_offset));
		else {
			if (opcode == CEE_LDELEM_REF) {
				if (array->type->data.klass->valuetype)
					CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid array type is not a reference type for ldelem.ref 0x%04x", ctx->ip_offset));
				type = &array->type->data.klass->byval_arg;
			} else {
				MonoType *candidate = &array->type->data.klass->byval_arg;
				if (IS_STRICT_MODE (ctx)) {
					MonoType *underlying_type = mono_type_get_underlying_type_any (type);
					MonoType *underlying_candidate = mono_type_get_underlying_type_any (candidate);
					if ((IS_ONE_OF2 (underlying_type->type, MONO_TYPE_I4, MONO_TYPE_U4) && IS_ONE_OF2 (underlying_candidate->type, MONO_TYPE_I, MONO_TYPE_U)) ||
						(IS_ONE_OF2 (underlying_candidate->type, MONO_TYPE_I4, MONO_TYPE_U4) && IS_ONE_OF2 (underlying_type->type, MONO_TYPE_I, MONO_TYPE_U)))
						CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid array type on stack for ldelem.X at 0x%04x", ctx->ip_offset));
				}
				if (!verify_type_compatibility_full (ctx, type, candidate, TRUE))
					CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid array type on stack for ldelem.X at 0x%04x", ctx->ip_offset));
			}
		}
	}

	set_stack_value (ctx, stack_push (ctx), type, FALSE);
#undef IS_ONE_OF2
}

Project: mono
File: verify.c

gboolean
mono_verifier_verify_class (MonoClass *class)
{
	/* The verifier was disabled at compile time */
	return TRUE;

Project: mono
File: reflection.c

mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
{
	guint32 parent = mono_image_typedef_or_ref (assembly, type);
	return mono_image_add_memberef_row (assembly, parent, name, sig);
}

Project: mono
File: reflection.c

mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
{
	MonoMethodInflated *imethod;
	guint32 token;
	
	token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
	if (token)
		return token;

	g_assert (method->is_inflated);
	imethod = (MonoMethodInflated *) method;

	if (mono_method_signature (imethod->declaring)->generic_param_count) {
		token = method_encode_methodspec (assembly, method);
	} else {
		guint32 sig = method_encode_signature (
			assembly, mono_method_signature (imethod->declaring));
		token = mono_image_get_memberref_token (
			assembly, &method->klass->byval_arg, method->name, sig);
	}

	g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
	return token;
}

Project: mono
File: reflection.c

mono_image_get_type_info (MonoDomain *domain, MonoReflectionTypeBuilder *tb, MonoDynamicImage *assembly)
{
	MonoDynamicTable *table;
	guint *values;
	int i, is_object = 0, is_system = 0;
	char *n;

	table = &assembly->tables [MONO_TABLE_TYPEDEF];
	values = table->values + tb->table_idx * MONO_TYPEDEF_SIZE;
	values [MONO_TYPEDEF_FLAGS] = tb->attrs;
	n = mono_string_to_utf8 (tb->name);
	if (strcmp (n, "Object") == 0)
		is_object++;
	values [MONO_TYPEDEF_NAME] = string_heap_insert (&assembly->sheap, n);
	g_free (n);
	n = mono_string_to_utf8 (tb->nspace);
	if (strcmp (n, "System") == 0)
		is_system++;
	values [MONO_TYPEDEF_NAMESPACE] = string_heap_insert (&assembly->sheap, n);
	g_free (n);
	if (tb->parent && !(is_system && is_object) && 
			!(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
		values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent));
	} else {
		values [MONO_TYPEDEF_EXTENDS] = 0;
	}
	values [MONO_TYPEDEF_FIELD_LIST] = assembly->tables [MONO_TABLE_FIELD].next_idx;
	values [MONO_TYPEDEF_METHOD_LIST] = assembly->tables [MONO_TABLE_METHOD].next_idx;

	/*
	 * if we have explicitlayout or sequentiallayouts, output data in the
	 * ClassLayout table.
	 */
	if (((tb->attrs & TYPE_ATTRIBUTE_LAYOUT_MASK) != TYPE_ATTRIBUTE_AUTO_LAYOUT) &&
			((tb->class_size > 0) || (tb->packing_size > 0))) {
		table = &assembly->tables [MONO_TABLE_CLASSLAYOUT];
		table->rows++;
		alloc_table (table, table->rows);
		values = table->values + table->rows * MONO_CLASS_LAYOUT_SIZE;
		values [MONO_CLASS_LAYOUT_PARENT] = tb->table_idx;
		values [MONO_CLASS_LAYOUT_CLASS_SIZE] = tb->class_size;
		values [MONO_CLASS_LAYOUT_PACKING_SIZE] = tb->packing_size;
	}

	/* handle interfaces */
	if (tb->interfaces) {
		table = &assembly->tables [MONO_TABLE_INTERFACEIMPL];
		i = table->rows;
		table->rows += mono_array_length (tb->interfaces);
		alloc_table (table, table->rows);
		values = table->values + (i + 1) * MONO_INTERFACEIMPL_SIZE;
		for (i = 0; i < mono_array_length (tb->interfaces); ++i) {
			MonoReflectionType* iface = (MonoReflectionType*) mono_array_get (tb->interfaces, gpointer, i);
			values [MONO_INTERFACEIMPL_CLASS] = tb->table_idx;
			values [MONO_INTERFACEIMPL_INTERFACE] = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle (iface));
			values += MONO_INTERFACEIMPL_SIZE;
		}
	}

	/* handle fields */
	if (tb->fields) {
		table = &assembly->tables [MONO_TABLE_FIELD];
		table->rows += tb->num_fields;
		alloc_table (table, table->rows);
		for (i = 0; i < tb->num_fields; ++i)
			mono_image_get_field_info (
				mono_array_get (tb->fields, MonoReflectionFieldBuilder*, i), assembly);
	}

	/* handle constructors */
	if (tb->ctors) {
		table = &assembly->tables [MONO_TABLE_METHOD];
		table->rows += mono_array_length (tb->ctors);
		alloc_table (table, table->rows);
		for (i = 0; i < mono_array_length (tb->ctors); ++i)
			mono_image_get_ctor_info (domain,
				mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i), assembly);
	}

	/* handle methods */
	if (tb->methods) {
		table = &assembly->tables [MONO_TABLE_METHOD];
		table->rows += tb->num_methods;
		alloc_table (table, table->rows);
		for (i = 0; i < tb->num_methods; ++i)
			mono_image_get_method_info (
				mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i), assembly);
	}

	/* Do the same with properties etc.. */
	if (tb->events && mono_array_length (tb->events)) {
		table = &assembly->tables [MONO_TABLE_EVENT];
		table->rows += mono_array_length (tb->events);
		alloc_table (table, table->rows);
		table = &assembly->tables [MONO_TABLE_EVENTMAP];
		table->rows ++;
		alloc_table (table, table->rows);
		values = table->values + table->rows * MONO_EVENT_MAP_SIZE;
		values [MONO_EVENT_MAP_PARENT] = tb->table_idx;
		values [MONO_EVENT_MAP_EVENTLIST] = assembly->tables [MONO_TABLE_EVENT].next_idx;
		for (i = 0; i < mono_array_length (tb->events); ++i)
			mono_image_get_event_info (
				mono_array_get (tb->events, MonoReflectionEventBuilder*, i), assembly);
	}
	if (tb->properties && mono_array_length (tb->properties)) {
		table = &assembly->tables [MONO_TABLE_PROPERTY];
		table->rows += mono_array_length (tb->properties);
		alloc_table (table, table->rows);
		table = &assembly->tables [MONO_TABLE_PROPERTYMAP];
		table->rows ++;
		alloc_table (table, table->rows);
		values = table->values + table->rows * MONO_PROPERTY_MAP_SIZE;
		values [MONO_PROPERTY_MAP_PARENT] = tb->table_idx;
		values [MONO_PROPERTY_MAP_PROPERTY_LIST] = assembly->tables [MONO_TABLE_PROPERTY].next_idx;
		for (i = 0; i < mono_array_length (tb->properties); ++i)
			mono_image_get_property_info (
				mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly);
	}

	/* handle generic parameters */
	if (tb->generic_params) {
		table = &assembly->tables [MONO_TABLE_GENERICPARAM];
		table->rows += mono_array_length (tb->generic_params);
		alloc_table (table, table->rows);
		for (i = 0; i < mono_array_length (tb->generic_params); ++i) {
			guint32 owner = MONO_TYPEORMETHOD_TYPE | (tb->table_idx << MONO_TYPEORMETHOD_BITS);

			mono_image_get_generic_param_info (
				mono_array_get (tb->generic_params, MonoReflectionGenericParam*, i), owner, assembly);
		}
	}

	mono_image_add_decl_security (assembly, 
		mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx), tb->permissions);

	if (tb->subtypes) {
		MonoDynamicTable *ntable;
		
		ntable = &assembly->tables [MONO_TABLE_NESTEDCLASS];
		ntable->rows += mono_array_length (tb->subtypes);
		alloc_table (ntable, ntable->rows);
		values = ntable->values + ntable->next_idx * MONO_NESTED_CLASS_SIZE;

		for (i = 0; i < mono_array_length (tb->subtypes); ++i) {
			MonoReflectionTypeBuilder *subtype = mono_array_get (tb->subtypes, MonoReflectionTypeBuilder*, i);

			values [MONO_NESTED_CLASS_NESTED] = subtype->table_idx;
			values [MONO_NESTED_CLASS_ENCLOSING] = tb->table_idx;
			/*g_print ("nesting %s (%d) in %s (%d) (rows %d/%d)\n",
				mono_string_to_utf8 (subtype->name), subtype->table_idx,
				mono_string_to_utf8 (tb->name), tb->table_idx,
				ntable->next_idx, ntable->rows);*/
			values += MONO_NESTED_CLASS_SIZE;
			ntable->next_idx++;
		}
	}
}

Project: mono
File: verify.c

generic_arguments_respect_constraints (VerifyContext *ctx, MonoGenericContainer *gc, MonoGenericContext *context, MonoGenericInst *ginst)
{
	int i;
	for (i = 0; i < ginst->type_argc; ++i) {
		MonoType *type = ginst->type_argv [i];
		MonoGenericParam *target = mono_generic_container_get_param (gc, i);
		MonoGenericParam *candidate;
		MonoClass *candidate_class;

		if (!mono_type_is_generic_argument (type))
			continue;

		if (!is_valid_type_in_context (ctx, type))
			return FALSE;

		candidate = verifier_get_generic_param_from_type (ctx, type);
		candidate_class = mono_class_from_mono_type (type);

		if (!mono_generic_param_is_constraint_compatible (ctx, target, candidate, candidate_class, context))
			return FALSE;
	}
	return TRUE;
}

Project: mono
File: reflection.c

reflected_hash (gconstpointer a) {
	const ReflectedEntry *ea = a;
	return mono_aligned_addr_hash (ea->item);
}

Project: mono
File: verify.c

do_unbox_any (VerifyContext *ctx, int klass_token)
{
	ILStackDesc *value;
	MonoType *type = get_boxable_mono_type (ctx, klass_token, "unbox.any");

	if (!type)
		return;
 
	if (!check_underflow (ctx, 1))
		return;

	value = stack_pop (ctx);

	/*Value should be: a boxed valuetype or a reference type*/
	if (!(stack_slot_get_type (value) == TYPE_COMPLEX &&
		(stack_slot_is_boxed_value (value) || !mono_class_from_mono_type (value->type)->valuetype)))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type %s at stack for unbox.any operation at 0x%04x", stack_slot_get_name (value), ctx->ip_offset));
 
	set_stack_value (ctx, stack_push (ctx), type, FALSE);
}

Project: mono
File: reflection.c

register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
{
	CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
}

Project: mono
File: reflection.c

guint32
mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types)
{
	g_assert_not_reached ();
	return 0;

Project: mono
File: reflection.c

mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, MonoArray *permissions)
{
	MonoDynamicTable *table;
	guint32 *values;
	guint32 count, i, idx;
	MonoReflectionPermissionSet *perm;

	if (!permissions)
		return;

	count = mono_array_length (permissions);
	table = &assembly->tables [MONO_TABLE_DECLSECURITY];
	table->rows += count;
	alloc_table (table, table->rows);

	for (i = 0; i < mono_array_length (permissions); ++i) {
		perm = (MonoReflectionPermissionSet*)mono_array_addr (permissions, MonoReflectionPermissionSet, i);

		values = table->values + table->next_idx * MONO_DECL_SECURITY_SIZE;

		idx = mono_metadata_token_index (parent_token);
		idx <<= MONO_HAS_DECL_SECURITY_BITS;
		switch (mono_metadata_token_table (parent_token)) {
		case MONO_TABLE_TYPEDEF:
			idx |= MONO_HAS_DECL_SECURITY_TYPEDEF;
			break;
		case MONO_TABLE_METHOD:
			idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
			break;
		case MONO_TABLE_ASSEMBLY:
			idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
			break;
		default:
			g_assert_not_reached ();
		}

		values [MONO_DECL_SECURITY_ACTION] = perm->action;
		values [MONO_DECL_SECURITY_PARENT] = idx;
		values [MONO_DECL_SECURITY_PERMISSIONSET] = add_mono_string_to_blob_cached (assembly, perm->pset);

		++table->next_idx;
	}
}

Project: mono
File: reflection.c

mono_module_file_get_object (MonoDomain *domain, MonoImage *image, int table_index)
{
	static MonoClass *module_type;
	MonoReflectionModule *res;
	MonoTableInfo *table;
	guint32 cols [MONO_FILE_SIZE];
	const char *name;
	guint32 i, name_idx;
	const char *val;
	
	if (!module_type) {
		MonoClass *class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoModule");
		if (class == NULL)
			class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
		g_assert (class);
		module_type = class;
	}
	res = (MonoReflectionModule *)mono_object_new (domain, module_type);

	table = &image->tables [MONO_TABLE_FILE];
	g_assert (table_index < table->rows);
	mono_metadata_decode_row (table, table_index, cols, MONO_FILE_SIZE);

	res->image = NULL;
	MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
	name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);

	/* Check whenever the row has a corresponding row in the moduleref table */
	table = &image->tables [MONO_TABLE_MODULEREF];
	for (i = 0; i < table->rows; ++i) {
		name_idx = mono_metadata_decode_row_col (table, i, MONO_MODULEREF_NAME);
		val = mono_metadata_string_heap (image, name_idx);
		if (strcmp (val, name) == 0)
			res->image = image->modules [i];
	}

	MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name));
	MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name));
	MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name));
	res->is_resource = cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA;
	res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);

	return res;
}

Project: mono
File: reflection.c

void
mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
{
	*overrides = NULL;
	*num_overrides = 0;

Project: mono
File: reflection.c

void
mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam)
{
	MonoGenericParamFull *param;
	MonoImage *image;
	MonoClass *pklass;

	MONO_ARCH_SAVE_REGS;

	param = g_new0 (MonoGenericParamFull, 1);

	if (gparam->mbuilder) {
		if (!gparam->mbuilder->generic_container) {
			MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)gparam->mbuilder->type;
			MonoClass *klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb));
			gparam->mbuilder->generic_container = 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->image = klass->image;
		}
		param->param.owner = gparam->mbuilder->generic_container;
	} else if (gparam->tbuilder) {
		if (!gparam->tbuilder->generic_container) {
			MonoClass *klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)gparam->tbuilder));
			gparam->tbuilder->generic_container = mono_image_alloc0 (klass->image, sizeof (MonoGenericContainer));
			gparam->tbuilder->generic_container->owner.klass = klass;
		}
		param->param.owner = gparam->tbuilder->generic_container;
	}

	param->info.name = mono_string_to_utf8 (gparam->name);
	param->param.num = gparam->index;

	image = &gparam->tbuilder->module->dynamic_image->image;
	pklass = mono_class_from_generic_parameter ((MonoGenericParam *) param, image, gparam->mbuilder != NULL);

	gparam->type.type = &pklass->byval_arg;

	mono_class_set_ref_info (pklass, gparam);
	mono_image_lock (image);
	image->reflection_info_unregister_classes = g_slist_prepend (image->reflection_info_unregister_classes, pklass);
	mono_image_unlock (image);

Project: mono
File: reflection.c

mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
{
	MonoArray *result;
	MonoObject *attr;
	int i, n;

	n = 0;
	for (i = 0; i < cinfo->num_attrs; ++i) {
		if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass))
			n ++;
	}

	result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, n);
	n = 0;
	for (i = 0; i < cinfo->num_attrs; ++i) {
		if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
			attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
			mono_array_setref (result, n, attr);
			n ++;
		}
	}
	return result;
}

Project: mono
File: reflection.c

mono_image_get_method_on_inst_token (MonoDynamicImage *assembly, MonoReflectionMethodOnTypeBuilderInst *m, gboolean create_methodspec)
{
	guint32 sig, token = 0;
	MonoType *type;
	MonoClass *klass;

	if (m->method_args) {
		MonoMethod *inflated;

		inflated = mono_reflection_method_on_tb_inst_get_handle (m);
		if (create_methodspec)
			token = mono_image_get_methodspec_token (assembly, inflated);
		else
			token = mono_image_get_inflated_method_token (assembly, inflated);
		return token;
	}

	token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, m));
	if (token)
		return token;

	if (is_sre_method_builder (mono_object_class (m->mb))) {
		MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)m->mb;
		MonoGenericClass *gclass;
		ReflectionMethodBuilder rmb;
		char *name;

		type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
		klass = mono_class_from_mono_type (type);
		gclass = type->data.generic_class;
		g_assert (gclass->is_dynamic);

		reflection_methodbuilder_from_method_builder (&rmb, mb);

		name = mono_string_to_utf8 (rmb.name);

		sig = method_builder_encode_signature (assembly, &rmb);

		token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
		g_free (name);		
	} else if (is_sr_mono_method (mono_object_class (m->mb))) {
		MonoMethod *mm = ((MonoReflectionMethod *)m->mb)->method;

		type = mono_reflection_type_get_handle ((MonoReflectionType*)m->inst);
		klass = mono_class_from_mono_type (type);

		sig = method_encode_signature (assembly, mono_method_signature (mm));
		token = mono_image_get_memberref_token (assembly, &klass->byval_arg, mm->name, sig);
	} else {
		char *name = mono_type_get_full_name (mono_object_class (m->mb));
		g_error ("mono_image_get_method_on_inst_token: don't know how to handle %s", name);
	}

	mono_g_hash_table_insert (assembly->handleref_managed, m, GUINT_TO_POINTER (token));
	return token;
}

Project: mono
File: reflection.c

mono_image_create_method_token (MonoDynamicImage *assembly, MonoObject *obj, MonoArray *opt_param_types)
{
	MonoClass *klass;
	guint32 token = 0;
	MonoMethodSignature *sig;

	klass = obj->vtable->klass;
	if (strcmp (klass->name, "MonoMethod") == 0) {
		MonoMethod *method = ((MonoReflectionMethod *)obj)->method;
		MonoMethodSignature *old;
		guint32 sig_token, parent;
		int nargs, i;

		g_assert (opt_param_types && (mono_method_signature (method)->sentinelpos >= 0));

		nargs = mono_array_length (opt_param_types);
		old = mono_method_signature (method);
		sig = mono_metadata_signature_alloc ( &assembly->image, old->param_count + nargs);

		sig->hasthis = old->hasthis;
		sig->explicit_this = old->explicit_this;
		sig->call_convention = old->call_convention;
		sig->generic_param_count = old->generic_param_count;
		sig->param_count = old->param_count + nargs;
		sig->sentinelpos = old->param_count;
		sig->ret = old->ret;

		for (i = 0; i < old->param_count; i++)
			sig->params [i] = old->params [i];

		for (i = 0; i < nargs; i++) {
			MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
			sig->params [old->param_count + i] = mono_reflection_type_get_handle (rt);
		}

		parent = mono_image_typedef_or_ref (assembly, &method->klass->byval_arg);
		g_assert ((parent & MONO_TYPEDEFORREF_MASK) == MONO_MEMBERREF_PARENT_TYPEREF);
		parent >>= MONO_TYPEDEFORREF_BITS;

		parent <<= MONO_MEMBERREF_PARENT_BITS;
		parent |= MONO_MEMBERREF_PARENT_TYPEREF;

		sig_token = method_encode_signature (assembly, sig);
		token = mono_image_get_varargs_method_token (assembly, parent, method->name, sig_token);
	} else if (strcmp (klass->name, "MethodBuilder") == 0) {
		MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
		ReflectionMethodBuilder rmb;
		guint32 parent, sig_token;
		int nopt_args, nparams, ngparams, i;
		char *name;

		reflection_methodbuilder_from_method_builder (&rmb, mb);
		rmb.opt_types = opt_param_types;
		nopt_args = mono_array_length (opt_param_types);

		nparams = rmb.parameters ? mono_array_length (rmb.parameters): 0;
		ngparams = rmb.generic_params ? mono_array_length (rmb.generic_params): 0;
		sig = mono_metadata_signature_alloc (&assembly->image, nparams + nopt_args);

		sig->hasthis = !(rmb.attrs & METHOD_ATTRIBUTE_STATIC);
		sig->explicit_this = (rmb.call_conv & 0x40) == 0x40;
		sig->call_convention = rmb.call_conv;
		sig->generic_param_count = ngparams;
		sig->param_count = nparams + nopt_args;
		sig->sentinelpos = nparams;
		sig->ret = mono_reflection_type_get_handle (rmb.rtype);

		for (i = 0; i < nparams; i++) {
			MonoReflectionType *rt = mono_array_get (rmb.parameters, MonoReflectionType *, i);
			sig->params [i] = mono_reflection_type_get_handle (rt);
		}

		for (i = 0; i < nopt_args; i++) {
			MonoReflectionType *rt = mono_array_get (opt_param_types, MonoReflectionType *, i);
			sig->params [nparams + i] = mono_reflection_type_get_handle (rt);
		}

		sig_token = method_builder_encode_signature (assembly, &rmb);

		parent = mono_image_create_token (assembly, obj, TRUE, TRUE);
		g_assert (mono_metadata_token_table (parent) == MONO_TABLE_METHOD);

		parent = mono_metadata_token_index (parent) << MONO_MEMBERREF_PARENT_BITS;
		parent |= MONO_MEMBERREF_PARENT_METHODDEF;

		name = mono_string_to_utf8 (rmb.name);
		token = mono_image_get_varargs_method_token (
			assembly, parent, name, sig_token);
		g_free (name);
	} else {
		g_error ("requested method token for %s\n", klass->name);
	}

	g_hash_table_insert (assembly->vararg_aux_hash, GUINT_TO_POINTER (token), sig);
	mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
	return token;
}

Project: mono
File: reflection.c

static gboolean
is_sre_generic_instance (MonoClass *class)
{
	return FALSE;

Project: mono
File: reflection.c

string_heap_init (MonoDynamicStream *sh)
{
	sh->index = 0;
	sh->alloc_size = 4096;
	sh->data = g_malloc (4096);
	sh->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
	string_heap_insert (sh, "");
}

Project: mono
File: verify.c

static gboolean
recursive_mark_constraint_args (MonoBitSet *used_args, MonoGenericContainer *gc, MonoType *type)
{
	int idx;
	MonoClass **constraints;
	MonoGenericParamInfo *param_info;

	g_assert (mono_type_is_generic_argument (type));

	idx = mono_type_get_generic_param_num (type);
	if (mono_bitset_test_fast (used_args, idx))
		return FALSE;

	mono_bitset_set_fast (used_args, idx);
	param_info = mono_generic_container_get_param_info (gc, idx);

	if (!param_info->constraints)
		return TRUE;

	for (constraints = param_info->constraints; *constraints; ++constraints) {
		MonoClass *ctr = *constraints;
		MonoType *constraint_type = &ctr->byval_arg;

		if (mono_type_is_generic_argument (constraint_type) && !recursive_mark_constraint_args (used_args, gc, constraint_type))
			return FALSE;
	}
	return TRUE;

Project: mono
File: reflection.c

mono_reflection_resolve_custom_attribute_data (MonoReflectionMethod *ref_method, MonoReflectionAssembly *assembly, gpointer data, guint32 len, MonoArray **ctor_args, MonoArray **named_args)
{
	MonoDomain *domain;
	MonoArray *typedargs, *namedargs;
	MonoImage *image;
	MonoMethod *method;
	CattrNamedArg *arginfo;
	int i;

	*ctor_args = NULL;
	*named_args = NULL;

	if (len == 0)
		return;

	image = assembly->assembly->image;
	method = ref_method->method;
	domain = mono_object_domain (ref_method);

	if (!mono_class_init (method->klass))
		mono_raise_exception (mono_class_get_exception_for_failure (method->klass));

	mono_reflection_create_custom_attr_data_args (image, method, data, len, &typedargs, &namedargs, &arginfo);
	if (mono_loader_get_last_error ())
		mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));

	if (!typedargs || !namedargs)
		return;

	for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
		MonoObject *obj = mono_array_get (typedargs, MonoObject*, i);
		MonoObject *typedarg;

		typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj);
		mono_array_setref (typedargs, i, typedarg);
	}

	for (i = 0; i < mono_array_length (namedargs); ++i) {
		MonoObject *obj = mono_array_get (namedargs, MonoObject*, i);
		MonoObject *typedarg, *namedarg, *minfo;

		if (arginfo [i].prop)
			minfo = (MonoObject*)mono_property_get_object (domain, NULL, arginfo [i].prop);
		else
			minfo = (MonoObject*)mono_field_get_object (domain, NULL, arginfo [i].field);

		typedarg = create_cattr_typed_arg (arginfo [i].type, obj);
		namedarg = create_cattr_named_arg (minfo, typedarg);

		mono_array_setref (namedargs, i, namedarg);
	}

	*ctor_args = typedargs;
	*named_args = namedargs;
}

Project: mono
File: verify.c

gboolean
mono_verifier_is_enabled_for_method (MonoMethod *method)
{
	return mono_verifier_is_enabled_for_class (method->klass) && method->wrapper_type == MONO_WRAPPER_NONE;

Project: mono
File: verify.c

init_verifier_stats (void)
{
	static gboolean inited;
	if (!inited) {
		inited = TRUE;
		mono_counters_register ("Maximum memory allocated during verification", MONO_COUNTER_METADATA | MONO_COUNTER_INT, &max_allocated_memory);
		mono_counters_register ("Maximum memory used during verification", MONO_COUNTER_METADATA | MONO_COUNTER_INT, &max_working_set);
		mono_counters_register ("Total memory allocated for verification", MONO_COUNTER_METADATA | MONO_COUNTER_INT, &total_allocated_memory);
	}
}

Project: mono
File: reflection.c

static MonoMarshalSpec*
mono_marshal_spec_from_builder (MonoImage *image, MonoAssembly *assembly,
								MonoReflectionMarshal *minfo)
{
	MonoMarshalSpec *res;

	res = image_g_new0 (image, MonoMarshalSpec, 1);
	res->native = minfo->type;

	switch (minfo->type) {
	case MONO_NATIVE_LPARRAY:
		res->data.array_data.elem_type = minfo->eltype;
		if (minfo->has_size) {
			res->data.array_data.param_num = minfo->param_num;
			res->data.array_data.num_elem = minfo->count;
			res->data.array_data.elem_mult = minfo->param_num == -1 ? 0 : 1;
		}
		else {
			res->data.array_data.param_num = -1;
			res->data.array_data.num_elem = -1;
			res->data.array_data.elem_mult = -1;
		}
		break;

	case MONO_NATIVE_BYVALTSTR:
	case MONO_NATIVE_BYVALARRAY:
		res->data.array_data.num_elem = minfo->count;
		break;

	case MONO_NATIVE_CUSTOM:
		if (minfo->marshaltyperef)
			res->data.custom_data.custom_name =
				type_get_fully_qualified_name (mono_reflection_type_get_handle ((MonoReflectionType*)minfo->marshaltyperef));
		if (minfo->mcookie)
			res->data.custom_data.cookie = mono_string_to_utf8 (minfo->mcookie);
		break;

	default:
		break;
	}

	return res;

Project: mono
File: reflection.c

type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
	MonoClass *klass;
	MonoAssembly *ta;

	klass = mono_class_from_mono_type (type);
	if (!klass) 
		return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
	ta = klass->image->assembly;
	if (ta->dynamic || (ta == ass)) {
		if (klass->generic_class || klass->generic_container)
			/* For generic type definitions, we want T, while REFLECTION returns T<K> */
			return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
		else
			return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
	}

	return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
}

Project: mono
File: reflection.c

mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
{
	char *name;
	MonoImage *image;
	MonoImageOpenStatus status;
	MonoDynamicAssembly *assembly;
	guint32 module_count;
	MonoImage **new_modules;
	gboolean *new_modules_loaded;
	
	name = mono_string_to_utf8 (fileName);

	image = mono_image_open (name, &status);
	if (!image) {
		MonoException *exc;
		if (status == MONO_IMAGE_ERROR_ERRNO)
			exc = mono_get_exception_file_not_found (fileName);
		else
			exc = mono_get_exception_bad_image_format (name);
		g_free (name);
		mono_raise_exception (exc);
	}

	g_free (name);

	assembly = ab->dynamic_assembly;
	image->assembly = (MonoAssembly*)assembly;

	module_count = image->assembly->image->module_count;
	new_modules = g_new0 (MonoImage *, module_count + 1);
	new_modules_loaded = g_new0 (gboolean, module_count + 1);

	if (image->assembly->image->modules)
		memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
	if (image->assembly->image->modules_loaded)
		memcpy (new_modules_loaded, image->assembly->image->modules_loaded, module_count * sizeof (gboolean));
	new_modules [module_count] = image;
	new_modules_loaded [module_count] = TRUE;
	mono_image_addref (image);

	g_free (image->assembly->image->modules);
	image->assembly->image->modules = new_modules;
	image->assembly->image->modules_loaded = new_modules_loaded;
	image->assembly->image->module_count ++;

	mono_assembly_load_references (image, &status);
	if (status) {
		mono_image_close (image);
		mono_raise_exception (mono_get_exception_file_not_found (fileName));
	}

	return mono_module_get_object (mono_domain_get (), image);
}

Project: mono
File: verify.c

static gboolean
verify_interfaces (MonoClass *class)
{
	int i;
	for (i = 0; i < class->interface_count; ++i) {
		MonoClass *iface = class->interfaces [i];
		if (!(iface->flags & TYPE_ATTRIBUTE_INTERFACE))
			return FALSE;
	}
	return TRUE;

Project: mono
File: verify.c

mono_type_from_stack_slot (ILStackDesc *slot)
{
	if (stack_slot_is_managed_pointer (slot))
		return mono_type_get_type_byref (slot->type);
	return slot->type;
}

Project: mono
File: verify.c

verifier_load_method (VerifyContext *ctx, int token, const char *opcode) {
	MonoMethod* method;
	
	if (!IS_METHOD_DEF_OR_REF_OR_SPEC (token) || !token_bounds_check (ctx->image, token)) {
		ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid method token 0x%08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
		return NULL;
	}

	method = mono_get_method_full (ctx->image, token, NULL, ctx->generic_context);

	if (!method || mono_loader_get_last_error ()) {
		ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Cannot load method from token 0x%08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
		mono_loader_clear_error ();
		return NULL;
	}
	
	if (mono_method_is_valid_in_context (ctx, method) == RESULT_INVALID)
		return NULL;

	return method;
}

Project: mono
File: reflection.c

void
mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
{
	g_assert_not_reached ();

Project: mono
File: reflection.c

create_cattr_named_arg (void *minfo, MonoObject *typedarg)
{
	static MonoClass *klass;
	static MonoMethod *ctor;
	MonoObject *retval;
	void *unboxed, *params [2];

	if (!klass)
		klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeNamedArgument");
	if (!ctor)
		ctor = mono_class_get_method_from_name (klass, ".ctor", 2);

	params [0] = minfo;
	params [1] = typedarg;
	retval = mono_object_new (mono_domain_get (), klass);
	unboxed = mono_object_unbox (retval);
	mono_runtime_invoke (ctor, unboxed, params, NULL);

	return retval;
}

Project: mono
File: verify.c

mono_type_get_type_byref (MonoType *type)
{
	if (type->byref)
		return type;
	return &mono_class_from_mono_type (type)->this_arg;
}

Project: mono
File: reflection.c

MonoReflectionType*
mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
{
	g_assert_not_reached ();
	return NULL;

Project: mono
File: reflection.c

MonoArray*
mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
{
	g_assert_not_reached ();
	return NULL;

Project: mono
File: reflection.c

void
mono_reflection_setup_generic_class (MonoReflectionTypeBuilder *tb)
{

Project: mono
File: reflection.c

reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb)
{
	const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";

	memset (rmb, 0, sizeof (ReflectionMethodBuilder));

	rmb->ilgen = mb->ilgen;
	rmb->rtype = mono_type_get_object (mono_domain_get (), &mono_defaults.void_class->byval_arg);
	rmb->parameters = mb->parameters;
	rmb->generic_params = NULL;
	rmb->generic_container = NULL;
	rmb->opt_types = NULL;
	rmb->pinfo = mb->pinfo;
	rmb->attrs = mb->attrs;
	rmb->iattrs = mb->iattrs;
	rmb->call_conv = mb->call_conv;
	rmb->code = NULL;
	rmb->type = mb->type;
	rmb->name = mono_string_new (mono_domain_get (), name);
	rmb->table_idx = &mb->table_idx;
	rmb->init_locals = mb->init_locals;
	rmb->skip_visibility = FALSE;
	rmb->return_modreq = NULL;
	rmb->return_modopt = NULL;
	rmb->param_modreq = mb->param_modreq;
	rmb->param_modopt = mb->param_modopt;
	rmb->permissions = mb->permissions;
	rmb->mhandle = mb->mhandle;
	rmb->nrefs = 0;
	rmb->refs = NULL;
}

Project: mono
File: reflection.c

mono_reflection_get_custom_attrs_data (MonoObject *obj)
{
	MonoArray *result;
	MonoCustomAttrInfo *cinfo;

	cinfo = mono_reflection_get_custom_attrs_info (obj);
	if (cinfo) {
		result = mono_custom_attrs_data_construct (cinfo);
		if (!cinfo->cached)
			mono_custom_attrs_free (cinfo);
	} else
		result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, 0);

	return result;
}

Project: mono
File: verify.c

mono_free_verify_list (GSList *list)
{
	MonoVerifyInfoExtended *info;
	GSList *tmp;

	for (tmp = list; tmp; tmp = tmp->next) {
		info = tmp->data;
		g_free (info->info.message);
		g_free (info);
	}
	g_slist_free (list);
}

Project: mono
File: verify.c

static gboolean
verify_generic_parameters (MonoClass *class)
{
	int i;
	MonoGenericContainer *gc = class->generic_container;
	MonoBitSet *used_args = mono_bitset_new (gc->type_argc, 0);

	for (i = 0; i < gc->type_argc; ++i) {
		MonoGenericParamInfo *param_info = mono_generic_container_get_param_info (gc, i);
		MonoClass **constraints;

		if (!param_info->constraints)
			continue;

		mono_bitset_clear_all (used_args);
		mono_bitset_set_fast (used_args, i);

		for (constraints = param_info->constraints; *constraints; ++constraints) {
			MonoClass *ctr = *constraints;
			MonoType *constraint_type = &ctr->byval_arg;

			if (!mono_type_is_valid_type_in_context (constraint_type, &gc->context))
				goto fail;

			if (mono_type_is_generic_argument (constraint_type) && !recursive_mark_constraint_args (used_args, gc, constraint_type))
				goto fail;
		}
	}
	mono_bitset_free (used_args);
	return TRUE;

fail:
	mono_bitset_free (used_args);
	return FALSE;

Project: mono
File: reflection.c

MonoBoolean
mono_declsec_get_inheritdemands_method (MonoMethod *method, MonoDeclSecurityActions* demands)
{
	/* quick exit if no declarative security is present in the metadata */
	if (!method->klass->image->tables [MONO_TABLE_DECLSECURITY].rows)
		return FALSE;

	/* we want the original as the wrapper is "free" of the security informations */
	if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE || method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) {
		method = mono_marshal_method_from_wrapper (method);
		if (!method)
			return FALSE;
	}

	if (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY) {
		mono_class_init (method->klass);
		memset (demands, 0, sizeof (MonoDeclSecurityActions));

		return mono_declsec_get_method_demands_params (method, demands, 
			SECURITY_ACTION_INHERITDEMAND, SECURITY_ACTION_NONCASINHERITANCE, SECURITY_ACTION_INHERITDEMANDCHOICE);
	}
	return FALSE;

Project: mono
File: verify.c

merge_stacks (VerifyContext *ctx, ILCodeDesc *from, ILCodeDesc *to, gboolean start, gboolean external) 
{
	MonoError error;
	int i, j, k;
	stack_init (ctx, to);

	if (start) {
		if (to->flags == IL_CODE_FLAG_NOT_PROCESSED) 
			from->size = 0;
		else
			stack_copy (&ctx->eval, to);
		goto end_verify;
	} else if (!(to->flags & IL_CODE_STACK_MERGED)) {
		stack_copy (to, &ctx->eval);
		goto end_verify;
	}
	VERIFIER_DEBUG ( printf ("performing stack merge %d x %d\n", from->size, to->size); );

	if (from->size != to->size) {
		VERIFIER_DEBUG ( printf ("different stack sizes %d x %d at 0x%04x\n", from->size, to->size, ctx->ip_offset); );
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Could not merge stacks, different sizes (%d x %d) at 0x%04x", from->size, to->size, ctx->ip_offset)); 
		goto end_verify;
	}

	//FIXME we need to preserve CMMP attributes
	//FIXME we must take null literals into consideration.
	for (i = 0; i < from->size; ++i) {
		ILStackDesc *new_slot = from->stack + i;
		ILStackDesc *old_slot = to->stack + i;
		MonoType *new_type = mono_type_from_stack_slot (new_slot);
		MonoType *old_type = mono_type_from_stack_slot (old_slot);
		MonoClass *old_class = mono_class_from_mono_type (old_type);
		MonoClass *new_class = mono_class_from_mono_type (new_type);
		MonoClass *match_class = NULL;

		// S := T then U = S (new value is compatible with current value, keep current)
		if (verify_stack_type_compatibility (ctx, old_type, new_slot)) {
			copy_stack_value (new_slot, old_slot);
			continue;
		}

		// T := S then U = T (old value is compatible with current value, use new)
		if (verify_stack_type_compatibility (ctx, new_type, old_slot)) {
			copy_stack_value (old_slot, new_slot);
			continue;
		}

		if (mono_type_is_generic_argument (old_type) || mono_type_is_generic_argument (new_type)) {
			char *old_name = stack_slot_full_name (old_slot); 
			char *new_name = stack_slot_full_name (new_slot);
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Could not merge stack at depth %d, types not compatible: %s X %s at 0x%04x", i, old_name, new_name, ctx->ip_offset));
			g_free (old_name);
			g_free (new_name);
			goto end_verify;			
		} 

		//both are reference types, use closest common super type
		if (!mono_class_from_mono_type (old_type)->valuetype 
			&& !mono_class_from_mono_type (new_type)->valuetype
			&& !stack_slot_is_managed_pointer (old_slot)
			&& !stack_slot_is_managed_pointer (new_slot)) {
			
			for (j = MIN (old_class->idepth, new_class->idepth) - 1; j > 0; --j) {
				if (mono_metadata_type_equal (&old_class->supertypes [j]->byval_arg, &new_class->supertypes [j]->byval_arg)) {
					match_class = old_class->supertypes [j];
					goto match_found;
				}
			}

			mono_class_setup_interfaces (old_class, &error);
			if (!mono_error_ok (&error)) {
				CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot merge stacks due to a TypeLoadException %s at 0x%04x", mono_error_get_message (&error), ctx->ip_offset));
				mono_error_cleanup (&error);
				goto end_verify;
			}
			for (j = 0; j < old_class->interface_count; ++j) {
				for (k = 0; k < new_class->interface_count; ++k) {
					if (mono_metadata_type_equal (&old_class->interfaces [j]->byval_arg, &new_class->interfaces [k]->byval_arg)) {
						match_class = old_class->interfaces [j];
						goto match_found;
					}
				}
			}

			//No decent super type found, use object
			match_class = mono_defaults.object_class;
			goto match_found;
		} else if (is_compatible_boxed_valuetype (ctx,old_type, new_type, new_slot, FALSE) || is_compatible_boxed_valuetype (ctx, new_type, old_type, old_slot, FALSE)) {
			match_class = mono_defaults.object_class;
			goto match_found;
		}

		{
		char *old_name = stack_slot_full_name (old_slot); 
		char *new_name = stack_slot_full_name (new_slot);
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Could not merge stack at depth %d, types not compatible: %s X %s at 0x%04x", i, old_name, new_name, ctx->ip_offset)); 
		g_free (old_name);
		g_free (new_name);
		}
		set_stack_value (ctx, old_slot, &new_class->byval_arg, stack_slot_is_managed_pointer (old_slot));
		goto end_verify;

match_found:
		g_assert (match_class);
		set_stack_value (ctx, old_slot, &match_class->byval_arg, stack_slot_is_managed_pointer (old_slot));
		set_stack_value (ctx, new_slot, &match_class->byval_arg, stack_slot_is_managed_pointer (old_slot));
		continue;
	}

end_verify:
	if (external)
		to->flags |= IL_CODE_FLAG_WAS_TARGET;
	to->flags |= IL_CODE_STACK_MERGED;
}

Project: mono
File: reflection.c

mono_dynamic_image_free (MonoDynamicImage *image)
{
	MonoDynamicImage *di = image;
	GList *list;
	int i;

	if (di->methodspec)
		mono_g_hash_table_destroy (di->methodspec);
	if (di->typespec)
		g_hash_table_destroy (di->typespec);
	if (di->typeref)
		g_hash_table_destroy (di->typeref);
	if (di->handleref)
		g_hash_table_destroy (di->handleref);
	if (di->handleref_managed)
		mono_g_hash_table_destroy (di->handleref_managed);
	if (di->tokens)
		mono_g_hash_table_destroy (di->tokens);
	if (di->generic_def_objects)
		mono_g_hash_table_destroy (di->generic_def_objects);
	if (di->blob_cache) {
		g_hash_table_foreach (di->blob_cache, free_blob_cache_entry, NULL);
		g_hash_table_destroy (di->blob_cache);
	}
	if (di->standalonesig_cache)
		g_hash_table_destroy (di->standalonesig_cache);
	for (list = di->array_methods; list; list = list->next) {
		ArrayMethod *am = (ArrayMethod *)list->data;
		g_free (am->sig);
		g_free (am->name);
		g_free (am);
	}
	g_list_free (di->array_methods);
	if (di->gen_params) {
		for (i = 0; i < di->gen_params->len; i++) {
			GenericParamTableEntry *entry = g_ptr_array_index (di->gen_params, i);
			if (entry->gparam->type.type) {
				MonoGenericParam *param = entry->gparam->type.type->data.generic_param;
				g_free ((char*)mono_generic_param_info (param)->name);
				g_free (param);
			}
			mono_gc_deregister_root ((char*) &entry->gparam);
			g_free (entry);
		}
	 	g_ptr_array_free (di->gen_params, TRUE);
	}
	if (di->token_fixups)
		mono_g_hash_table_destroy (di->token_fixups);
	if (di->method_to_table_idx)
		g_hash_table_destroy (di->method_to_table_idx);
	if (di->field_to_table_idx)
		g_hash_table_destroy (di->field_to_table_idx);
	if (di->method_aux_hash)
		g_hash_table_destroy (di->method_aux_hash);
	if (di->vararg_aux_hash)
		g_hash_table_destroy (di->vararg_aux_hash);
	g_free (di->strong_name);
	g_free (di->win32_res);
	if (di->public_key)
		g_free (di->public_key);

	/*g_print ("string heap destroy for image %p\n", di);*/
	mono_dynamic_stream_reset (&di->sheap);
	mono_dynamic_stream_reset (&di->code);
	mono_dynamic_stream_reset (&di->resources);
	mono_dynamic_stream_reset (&di->us);
	mono_dynamic_stream_reset (&di->blob);
	mono_dynamic_stream_reset (&di->tstream);
	mono_dynamic_stream_reset (&di->guid);
	for (i = 0; i < MONO_TABLE_NUM; ++i) {
		g_free (di->tables [i].values);
	}
}

Project: mono
File: verify.c

do_store_static_field (VerifyContext *ctx, int token) {
	MonoClassField *field;
	MonoClass *klass;
	ILStackDesc *value;
	CLEAR_PREFIX (ctx, PREFIX_VOLATILE);

	if (!check_underflow (ctx, 1))
		return;

	value = stack_pop (ctx);

	if (!(field = verifier_load_field (ctx, token, &klass, "stsfld")))
		return;

	if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC)) { 
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Cannot store non static field at 0x%04x", ctx->ip_offset));
		return;
	}

	if (field->type->type == MONO_TYPE_TYPEDBYREF) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Typedbyref field is an unverfiable type in store static field at 0x%04x", ctx->ip_offset));
		return;
	}

	if (!IS_SKIP_VISIBILITY (ctx) && !mono_method_can_access_field_full (ctx->method, field, NULL))
		CODE_NOT_VERIFIABLE2 (ctx, g_strdup_printf ("Type at stack is not accessible at 0x%04x", ctx->ip_offset), MONO_EXCEPTION_FIELD_ACCESS);

	if (!verify_stack_type_compatibility (ctx, field->type, value)) {
		char *stack_name = stack_slot_full_name (value);
		char *field_name = mono_type_full_name (field->type);
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Incompatible type in static field store expected '%s' but found '%s' at 0x%04x",
				field_name, stack_name, ctx->ip_offset));
		g_free (field_name);
		g_free (stack_name);
	}
}

Project: mono
File: reflection.c

static void
check_array_for_usertypes (MonoArray *arr)
{
	int i;

	if (!arr)
		return;

	for (i = 0; i < mono_array_length (arr); ++i)
		RESOLVE_ARRAY_TYPE_ELEMENT (arr, i);

Project: mono
File: verify.c

gboolean
mono_verifier_verify_class (MonoClass *class)
{
	/*Neither <Module>, object or ifaces have parent.*/
	if (!class->parent &&
		class != mono_defaults.object_class && 
		!MONO_CLASS_IS_INTERFACE (class) &&
		(!class->image->dynamic && class->type_token != 0x2000001)) /*<Module> is the first type in the assembly*/
		return FALSE;
	if (class->parent && MONO_CLASS_IS_INTERFACE (class->parent))
		return FALSE;
	if (class->generic_container && (class->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT)
		return FALSE;
	if (class->generic_container && !verify_generic_parameters (class))
		return FALSE;
	if (!verify_class_for_overlapping_reference_fields (class))
		return FALSE;
	if (class->generic_class && !mono_class_is_valid_generic_instantiation (NULL, class))
		return FALSE;
	if (class->generic_class == NULL && !verify_class_fields (class))
		return FALSE;
	if (class->valuetype && !verify_valuetype_layout (class))
		return FALSE;
	if (!verify_interfaces (class))
		return FALSE;
	return TRUE;

Project: mono
File: verify.c

get_stack_type (MonoType *type)
{
	int mask = 0;
	int type_kind = type->type;
	if (type->byref)
		mask = POINTER_MASK;
	/*TODO handle CMMP_MASK */

handle_enum:
	switch (type_kind) {
	case MONO_TYPE_I1:
	case MONO_TYPE_U1:
	case MONO_TYPE_BOOLEAN:
	case MONO_TYPE_I2:
	case MONO_TYPE_U2:
	case MONO_TYPE_CHAR:
	case MONO_TYPE_I4:
	case MONO_TYPE_U4:
		return TYPE_I4 | mask;

	case MONO_TYPE_I:
	case MONO_TYPE_U:
		return TYPE_NATIVE_INT | mask;

	/* FIXME: the spec says that you cannot have a pointer to method pointer, do we need to check this here? */ 
	case MONO_TYPE_FNPTR:
	case MONO_TYPE_PTR:
	case MONO_TYPE_TYPEDBYREF:
		return TYPE_PTR | mask;

	case MONO_TYPE_VAR:
	case MONO_TYPE_MVAR:

	case MONO_TYPE_CLASS:
	case MONO_TYPE_STRING:
	case MONO_TYPE_OBJECT:
	case MONO_TYPE_SZARRAY:
	case MONO_TYPE_ARRAY:
		return TYPE_COMPLEX | mask;

	case MONO_TYPE_I8:
	case MONO_TYPE_U8:
		return TYPE_I8 | mask;

	case MONO_TYPE_R4:
	case MONO_TYPE_R8:
		return TYPE_R8 | mask;

	case MONO_TYPE_GENERICINST:
	case MONO_TYPE_VALUETYPE:
		if (mono_type_is_enum_type (type)) {
			type = mono_type_get_underlying_type_any (type);
			if (!type)
				return FALSE;
			type_kind = type->type;
			goto handle_enum;
		} else {
			return TYPE_COMPLEX | mask;
		}

	default:
		return TYPE_INV;
	}
}

Project: mono
File: reflection.c

mono_image_get_array_token (MonoDynamicImage *assembly, MonoReflectionArrayMethod *m)
{
	guint32 nparams, i;
	GList *tmp;
	char *name;
	MonoMethodSignature *sig;
	ArrayMethod *am;
	MonoType *mtype;

	name = mono_string_to_utf8 (m->name);
	nparams = mono_array_length (m->parameters);
	sig = g_malloc0 (MONO_SIZEOF_METHOD_SIGNATURE + sizeof (MonoType*) * nparams);
	sig->hasthis = 1;
	sig->sentinelpos = -1;
	sig->call_convention = reflection_cc_to_file (m->call_conv);
	sig->param_count = nparams;
	sig->ret = m->ret ? mono_reflection_type_get_handle (m->ret): &mono_defaults.void_class->byval_arg;
	mtype = mono_reflection_type_get_handle (m->parent);
	for (i = 0; i < nparams; ++i)
		sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i);

	for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
		am = tmp->data;
		if (strcmp (name, am->name) == 0 && 
				mono_metadata_type_equal (am->parent, mtype) &&
				mono_metadata_signature_equal (am->sig, sig)) {
			g_free (name);
			g_free (sig);
			m->table_idx = am->token & 0xffffff;
			return am->token;
		}
	}
	am = g_new0 (ArrayMethod, 1);
	am->name = name;
	am->sig = sig;
	am->parent = mtype;
	am->token = mono_image_get_memberref_token (assembly, am->parent, name,
		method_encode_signature (assembly, sig));
	assembly->array_methods = g_list_prepend (assembly->array_methods, am);
	m->table_idx = am->token & 0xffffff;
	return am->token;
}

Project: mono
File: verify.c

static gboolean
mono_opcode_is_prefix (int op)
{
	switch (op) {
	case MONO_CEE_UNALIGNED_:
	case MONO_CEE_VOLATILE_:
	case MONO_CEE_TAIL_:
	case MONO_CEE_CONSTRAINED_:
	case MONO_CEE_READONLY_:
		return TRUE;
	}
	return FALSE;

Project: mono
File: reflection.c

create_custom_attr_data (MonoImage *image, MonoCustomAttrEntry *cattr)
{
	static MonoMethod *ctor;
	MonoDomain *domain;
	MonoObject *attr;
	void *params [4];

	g_assert (image->assembly);

	if (!ctor)
		ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 4);

	domain = mono_domain_get ();
	attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
	params [0] = mono_method_get_object (domain, cattr->ctor, NULL);
	params [1] = mono_assembly_get_object (domain, image->assembly);
	params [2] = (gpointer)&cattr->data;
	params [3] = &cattr->data_size;
	mono_runtime_invoke (ctor, attr, params, NULL);
	return attr;
}

Project: mono
File: reflection.c

find_field_index (MonoClass *klass, MonoClassField *field) {
	int i;

	for (i = 0; i < klass->field.count; ++i) {
		if (field == &klass->fields [i])
			return klass->field.first + 1 + i;
	}
	return 0;
}

Project: mono
File: verify.c

gboolean
mono_verifier_is_enabled_for_class (MonoClass *klass)
{
	/* The verifier was disabled at compile time */
	return FALSE;

Project: mono
File: verify.c

in_any_block (MonoMethodHeader *header, guint offset)
{
	int i;
	MonoExceptionClause *clause;

	for (i = 0; i < header->num_clauses; ++i) {
		clause = &header->clauses [i];
		if (MONO_OFFSET_IN_CLAUSE (clause, offset))
			return 1;
		if (MONO_OFFSET_IN_HANDLER (clause, offset))
			return 1;
		if (MONO_OFFSET_IN_FILTER (clause, offset))
			return 1;
	}
	return 0;
}

Project: mono
File: reflection.c

mono_image_get_methodref_token_for_methodbuilder (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *method)
{
	guint32 token, parent, sig;
	ReflectionMethodBuilder rmb;
	char *name;
	MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)method->type;
	
	token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
	if (token)
		return token;

	name = mono_string_to_utf8 (method->name);
	reflection_methodbuilder_from_method_builder (&rmb, method);

	/*
	 * 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 = method_builder_encode_signature (assembly, &rmb);

	if (tb->generic_params)
		parent = create_generic_typespec (assembly, tb);
	else
		parent = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle ((MonoReflectionType*)rmb.type));

	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;
}

Project: mono
File: reflection.c

static void
encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value)
{
	int len;
	/* Preallocate a large enough buffer */
	if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
		char *str = type_get_qualified_name (type, NULL);
		len = strlen (str);
		g_free (str);
	} else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
		char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
		len = strlen (str);
		g_free (str);
	} else {
		len = 0;
	}
	len += strlen (name);

	if ((p-buffer) + 20 + len >= *buflen) {
		char *newbuf;
		*buflen *= 2;
		*buflen += len;
		newbuf = g_realloc (buffer, *buflen);
		p = newbuf + (p-buffer);
		buffer = newbuf;
	}

	encode_field_or_prop_type (type, p, &p);

	len = strlen (name);
	mono_metadata_encode_value (len, p, &p);
	memcpy (p, name, len);
	p += len;
	encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, buflen, type, value, NULL);
	*retp = p;
	*retbuffer = buffer;

Project: mono
File: reflection.c

mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
{
	MonoDynamicTable *table;
	guint32 *values;
	guint32 token, pclass;

	switch (parent & MONO_TYPEDEFORREF_MASK) {
	case MONO_TYPEDEFORREF_TYPEREF:
		pclass = MONO_MEMBERREF_PARENT_TYPEREF;
		break;
	case MONO_TYPEDEFORREF_TYPESPEC:
		pclass = MONO_MEMBERREF_PARENT_TYPESPEC;
		break;
	case MONO_TYPEDEFORREF_TYPEDEF:
		pclass = MONO_MEMBERREF_PARENT_TYPEDEF;
		break;
	default:
		g_warning ("unknown typeref or def token 0x%08x for %s", parent, name);
		return 0;
	}
	/* extract the index */
	parent >>= MONO_TYPEDEFORREF_BITS;

	table = &assembly->tables [MONO_TABLE_MEMBERREF];

	if (assembly->save) {
		alloc_table (table, table->rows + 1);
		values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
		values [MONO_MEMBERREF_CLASS] = pclass | (parent << MONO_MEMBERREF_PARENT_BITS);
		values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
		values [MONO_MEMBERREF_SIGNATURE] = sig;
	}

	token = MONO_TOKEN_MEMBER_REF | table->next_idx;
	table->next_idx ++;

	return token;
}

Project: mono
File: verify.c

do_ldelema (VerifyContext *ctx, int klass_token)
{
	ILStackDesc *index, *array, *res;
	MonoType *type = get_boxable_mono_type (ctx, klass_token, "ldelema");
	gboolean valid; 

	if (!type)
		return;

	if (!check_underflow (ctx, 2))
		return;

	index = stack_pop (ctx);
	array = stack_pop (ctx);

	if (stack_slot_get_type (index) != TYPE_I4 && stack_slot_get_type (index) != TYPE_NATIVE_INT)
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Index type(%s) for ldelema is not an int or a native int at 0x%04x", stack_slot_get_name (index), ctx->ip_offset));

	if (!stack_slot_is_null_literal (array)) {
		if (stack_slot_get_type (array) != TYPE_COMPLEX || array->type->type != MONO_TYPE_SZARRAY)
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid array type(%s) for ldelema at 0x%04x", stack_slot_get_name (array), ctx->ip_offset));
		else {
			if (get_stack_type (type) == TYPE_I4 || get_stack_type (type) == TYPE_NATIVE_INT) {
					valid = verify_type_compatibility_full (ctx, type, &array->type->data.klass->byval_arg, TRUE);
			} else {
				valid = mono_metadata_type_equal (type, &array->type->data.klass->byval_arg);
			}
			if (!valid)
				CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid array type on stack for ldelema at 0x%04x", ctx->ip_offset));
		}
	}

	res = stack_push (ctx);
	set_stack_value (ctx, res, type, TRUE);
	if (ctx->prefix_set & PREFIX_READONLY) {
		ctx->prefix_set &= ~PREFIX_READONLY;
		res->stype |= CMMP_MASK;
	}
}

Project: mono
File: verify.c

get_generic_param (VerifyContext *ctx, MonoType *param) 
{
	guint16 param_num = mono_type_get_generic_param_num (param);
	if (param->type == MONO_TYPE_VAR) {
		if (!ctx->generic_context->class_inst || ctx->generic_context->class_inst->type_argc <= param_num) {
			ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid generic type argument %d", param_num));
			return NULL;
		}
		return ctx->generic_context->class_inst->type_argv [param_num]->data.generic_param;
	}
	
	/*param must be a MVAR */
	if (!ctx->generic_context->method_inst || ctx->generic_context->method_inst->type_argc <= param_num) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid generic method argument %d", param_num));
		return NULL;
	}
	return ctx->generic_context->method_inst->type_argv [param_num]->data.generic_param;
	
}

Project: mono
File: reflection.c

mono_custom_attrs_from_method (MonoMethod *method)
{
	guint32 idx;

	/*
	 * An instantiated method has the same cattrs as the generic method definition.
	 *
	 * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
	 *           Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
	 */
	if (method->is_inflated)
		method = ((MonoMethodInflated *) method)->declaring;
	
	if (method->dynamic || method->klass->image->dynamic)
		return lookup_custom_attr (method->klass->image, method);

	if (!method->token)
		/* Synthetic methods */
		return NULL;

	idx = mono_method_get_index (method);
	idx <<= MONO_CUSTOM_ATTR_BITS;
	idx |= MONO_CUSTOM_ATTR_METHODDEF;
	return mono_custom_attrs_from_index (method->klass->image, idx);
}

Project: mono
File: reflection.c

mono_image_get_methodspec_token_for_generic_method_definition (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
{
	MonoDynamicTable *table;
	guint32 *values;
	guint32 token, mtoken = 0;

	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);
	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] = 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;
}

Project: mono
File: reflection.c

assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation)
{
	MonoDynamicTable *table;
	guint32 *values;

	table = &assembly->tables [MONO_TABLE_MANIFESTRESOURCE];
	table->rows++;
	alloc_table (table, table->rows);
	values = table->values + table->next_idx * MONO_MANIFEST_SIZE;
	values [MONO_MANIFEST_OFFSET] = rsrc->offset;
	values [MONO_MANIFEST_FLAGS] = rsrc->attrs;
	values [MONO_MANIFEST_NAME] = string_heap_insert_mstring (&assembly->sheap, rsrc->name);
	values [MONO_MANIFEST_IMPLEMENTATION] = implementation;
	table->next_idx++;
}

Project: mono
File: verify.c

is_array_type_compatible (MonoType *target, MonoType *candidate)
{
	MonoArrayType *left = target->data.array;
	MonoArrayType *right = candidate->data.array;

	g_assert (target->type == MONO_TYPE_ARRAY);
	g_assert (candidate->type == MONO_TYPE_ARRAY);

	if (left->rank != right->rank)
		return FALSE;

	return mono_class_is_assignable_from (left->eklass, right->eklass);
}

Project: mono
File: verify.c

gboolean
mono_verifier_is_method_valid_generic_instantiation (MonoMethod *method)
{
	return TRUE;

Project: mono
File: reflection.c

mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
{
	MonoTableInfo *ca;
	guint32 i, idx, method_index;
	guint32 param_list, param_last, param_pos, found;
	MonoImage *image;
	MonoReflectionMethodAux *aux;

	/*
	 * An instantiated method has the same cattrs as the generic method definition.
	 *
	 * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
	 *           Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
	 */
	if (method->is_inflated)
		method = ((MonoMethodInflated *) method)->declaring;

	if (method->klass->image->dynamic) {
		MonoCustomAttrInfo *res, *ainfo;
		int size;

		aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
		if (!aux || !aux->param_cattr)
			return NULL;

		/* Need to copy since it will be freed later */
		ainfo = aux->param_cattr [param];
		if (!ainfo)
			return NULL;
		size = MONO_SIZEOF_CUSTOM_ATTR_INFO + sizeof (MonoCustomAttrEntry) * ainfo->num_attrs;
		res = g_malloc0 (size);
		memcpy (res, ainfo, size);
		return res;
	}

	image = method->klass->image;
	method_index = mono_method_get_index (method);
	if (!method_index)
		return NULL;
	ca = &image->tables [MONO_TABLE_METHOD];

	param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
	if (method_index == ca->rows) {
		ca = &image->tables [MONO_TABLE_PARAM];
		param_last = ca->rows + 1;
	} else {
		param_last = mono_metadata_decode_row_col (ca, method_index, MONO_METHOD_PARAMLIST);
		ca = &image->tables [MONO_TABLE_PARAM];
	}
	found = FALSE;
	for (i = param_list; i < param_last; ++i) {
		param_pos = mono_metadata_decode_row_col (ca, i - 1, MONO_PARAM_SEQUENCE);
		if (param_pos == param) {
			found = TRUE;
			break;
		}
	}
	if (!found)
		return NULL;
	idx = i;
	idx <<= MONO_CUSTOM_ATTR_BITS;
	idx |= MONO_CUSTOM_ATTR_PARAMDEF;
	return mono_custom_attrs_from_index (image, idx);
}

Project: mono
File: verify.c

stack_init (VerifyContext *ctx, ILCodeDesc *state) 
{
	if (state->flags & IL_CODE_FLAG_STACK_INITED)
		return;
	state->size = state->max_size = 0;
	state->flags |= IL_CODE_FLAG_STACK_INITED;
}

Project: mono
File: verify.c

is_clause_in_range (MonoExceptionClause *clause, guint32 start, guint32 end)
{
	if (clause->try_offset >= start && clause->try_offset < end)
		return TRUE;
	if (HANDLER_START (clause) >= start && HANDLER_START (clause) < end)
		return TRUE;
	return FALSE;
}

Project: mono
File: reflection.c

compare_declsecurity_attrs (const void *a, const void *b)
{
	const guint32 *a_values = a;
	const guint32 *b_values = b;

	return a_values [MONO_DECL_SECURITY_PARENT] - b_values [MONO_DECL_SECURITY_PARENT];
}

Project: mono
File: reflection.c

mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
{
	MonoClass *klass;
	int i;

	if (!assemblyb->type_forwarders)
		return;

	for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
		MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType *, i);
		MonoType *type;
		if (!t)
			continue;

		type = mono_reflection_type_get_handle (t);
		g_assert (type);

		klass = mono_class_from_mono_type (type);

		add_exported_type (assemblyb, assembly, klass, 0);
	}
}

Project: mono
File: verify.c

mono_type_is_value_type (MonoType *type, const char *namespace, const char *name)
{
	return type->type == MONO_TYPE_VALUETYPE &&
		!strcmp (namespace, type->data.klass->name_space) &&
		!strcmp (name, type->data.klass->name);
}

Project: mono
File: reflection.c

static void
fix_partial_generic_class (MonoClass *klass)
{
	MonoClass *gklass = klass->generic_class->container_class;
	MonoDynamicGenericClass *dgclass;
	int i;

	if (klass->wastypebuilder)
		return;

	dgclass = (MonoDynamicGenericClass *)  klass->generic_class;
	if (klass->parent != gklass->parent) {
		MonoError error;
		MonoType *parent_type = mono_class_inflate_generic_type_checked (&gklass->parent->byval_arg, &klass->generic_class->context, &error);
		if (mono_error_ok (&error)) {
			MonoClass *parent = mono_class_from_mono_type (parent_type);
			mono_metadata_free_type (parent_type);
			if (parent != klass->parent) {
				/*fool mono_class_setup_parent*/
				klass->supertypes = NULL;
				mono_class_setup_parent (klass, parent);
			}
		} else {
			mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
			mono_error_cleanup (&error);
			if (gklass->wastypebuilder)
				klass->wastypebuilder = TRUE;
			return;
		}
	}

	if (!dgclass->initialized)
		return;

	if (klass->method.count != gklass->method.count) {
		klass->method.count = gklass->method.count;
		klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * (klass->method.count + 1));

		for (i = 0; i < klass->method.count; i++) {
			klass->methods [i] = mono_class_inflate_generic_method_full (
				gklass->methods [i], klass, mono_class_get_context (klass));
		}
	}

	if (klass->interface_count && klass->interface_count != gklass->interface_count) {
		klass->interface_count = gklass->interface_count;
		klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * gklass->interface_count);
		klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/

		for (i = 0; i < gklass->interface_count; ++i) {
			MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
			klass->interfaces [i] = mono_class_from_mono_type (iface_type);
			mono_metadata_free_type (iface_type);

			ensure_runtime_vtable (klass->interfaces [i]);
		}
		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);

		for (i = 0; i < klass->field.count; i++) {
			klass->fields [i] = gklass->fields [i];
			klass->fields [i].parent = klass;
			klass->fields [i].type = mono_class_inflate_generic_type (gklass->fields [i].type, mono_class_get_context (klass));
		}
	}

	/*We can only finish with this klass once it's parent has as well*/
	if (gklass->wastypebuilder)
		klass->wastypebuilder = TRUE;
	return;

Project: mono
File: reflection.c

void
mono_reflection_generic_class_initialize (MonoReflectionGenericClass *type, MonoArray *methods, 
					  MonoArray *ctors, MonoArray *fields, MonoArray *properties,
					  MonoArray *events)
{
	g_assert_not_reached ();

Project: mono
File: reflection.c

mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *field)
{
	MonoReflectionField *res;
	static MonoClass *monofield_klass;

	CHECK_OBJECT (MonoReflectionField *, field, klass);
	if (!monofield_klass)
		monofield_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoField");
	res = (MonoReflectionField *)mono_object_new (domain, monofield_klass);
	res->klass = klass;
	res->field = field;
	MONO_OBJECT_SETREF (res, name, mono_string_new (domain, mono_field_get_name (field)));

	if (is_field_on_inst (field)) {
		res->attrs = get_field_on_inst_generic_type (field)->attrs;
		MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
	} else {
		if (field->type)
			MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
		res->attrs = mono_field_get_flags (field);
	}
	CACHE_OBJECT (MonoReflectionField *, field, res, klass);
}

Project: mono
File: reflection.c

void
mono_reflection_register_with_runtime (MonoReflectionType *type)
{
	/* This is empty */

Project: mono
File: reflection.c

static void
ensure_runtime_vtable (MonoClass *klass)
{
	MonoReflectionTypeBuilder *tb = mono_class_get_ref_info (klass);
	int i, num, j;

	if (!klass->image->dynamic || (!tb && !klass->generic_class) || klass->wastypebuilder)
		return;
	if (klass->parent)
		ensure_runtime_vtable (klass->parent);

	if (tb) {
		num = tb->ctors? mono_array_length (tb->ctors): 0;
		num += tb->num_methods;
		klass->method.count = num;
		klass->methods = mono_image_alloc (klass->image, sizeof (MonoMethod*) * num);
		num = tb->ctors? mono_array_length (tb->ctors): 0;
		for (i = 0; i < num; ++i)
			klass->methods [i] = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i));
		num = tb->num_methods;
		j = i;
		for (i = 0; i < num; ++i)
			klass->methods [j++] = methodbuilder_to_mono_method (klass, mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i));
	
		if (tb->interfaces) {
			klass->interface_count = mono_array_length (tb->interfaces);
			klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
			for (i = 0; i < klass->interface_count; ++i) {
				MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i);
				klass->interfaces [i] = mono_class_from_mono_type (iface);
				ensure_runtime_vtable (klass->interfaces [i]);
			}
			klass->interfaces_inited = 1;
		}
	} else if (klass->generic_class){
		ensure_generic_class_runtime_vtable (klass);
	}

	if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
		for (i = 0; i < klass->method.count; ++i)
			klass->methods [i]->slot = i;
		
		klass->interfaces_packed = NULL; /*make setup_interface_offsets happy*/
		mono_class_setup_interface_offsets (klass);
		mono_class_setup_interface_id (klass);
	}

	/*
	 * The generic vtable is needed even if image->run is not set since some
	 * runtime code like ves_icall_Type_GetMethodsByName depends on 
	 * method->slot being defined.
	 */

	/* 
	 * tb->methods could not be freed since it is used for determining 
	 * overrides during dynamic vtable construction.
	 */

Project: mono
File: verify.c

mono_type_get_type_byval (MonoType *type)
{
	if (!type->byref)
		return type;
	return &mono_class_from_mono_type (type)->byval_arg;
}

Project: mono
File: reflection.c

stream_data_align (MonoDynamicStream *stream)
{
	char buf [4] = {0};
	guint32 count = stream->index % 4;

	/* we assume the stream data will be aligned */
	if (count)
		mono_image_add_stream_data (stream, buf, 4 - count);
}

Project: mono
File: verify.c

stack_peek (VerifyContext *ctx, int distance)
{
	g_assert (ctx->eval.size - distance > 0);
	return ctx->eval.stack + (ctx->eval.size - 1 - distance);
}

Project: mono
File: verify.c

stack_slot_is_complex_type_not_reference_type (ILStackDesc *slot)
{
	return stack_slot_get_type (slot) == TYPE_COMPLEX && !MONO_TYPE_IS_REFERENCE (slot->type) && !stack_slot_is_boxed_value (slot);
}

Project: mono
File: verify.c

do_static_branch (VerifyContext *ctx, int delta)
{
	int target = ctx->ip_offset + delta;
	if (target < 0 || target >= ctx->code_size) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("branch target out of code at 0x%04x", ctx->ip_offset));
		return;
	}

	switch (is_valid_branch_instruction (ctx->header, ctx->ip_offset, target)) {
	case 1:
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Branch target escapes out of exception block at 0x%04x", ctx->ip_offset));
		break;
	case 2:
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Branch target escapes out of exception block at 0x%04x", ctx->ip_offset));
		break;
	}

	ctx->target = target;
}

Project: mono
File: verify.c

gboolean
mono_verifier_class_is_valid_generic_instantiation (MonoClass *class)
{
	return TRUE;

Project: mono
File: reflection.c

method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
{
	/*
	 * FIXME: reuse code from method_encode_signature().
	 */
	SigBuffer buf;
	int i;
	guint32 nparams =  mb->parameters ? mono_array_length (mb->parameters): 0;
	guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
	guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
	guint32 idx;

	sigbuffer_init (&buf, 32);
	/* LAMESPEC: all the call conv spec is foobared */
	idx = mb->call_conv & 0x60; /* has-this, explicit-this */
	if (mb->call_conv & 2)
		idx |= 0x5; /* vararg */
	if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
		idx |= 0x20; /* hasthis */
	if (ngparams)
		idx |= 0x10; /* generic */
	sigbuffer_add_byte (&buf, idx);
	if (ngparams)
		sigbuffer_add_value (&buf, ngparams);
	sigbuffer_add_value (&buf, nparams + notypes);
	encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, &buf);
	encode_reflection_type (assembly, mb->rtype, &buf);
	for (i = 0; i < nparams; ++i) {
		MonoArray *modreq = NULL;
		MonoArray *modopt = NULL;
		MonoReflectionType *pt;

		if (mb->param_modreq && (i < mono_array_length (mb->param_modreq)))
			modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
		if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
			modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
		encode_custom_modifiers (assembly, modreq, modopt, &buf);
		pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
		encode_reflection_type (assembly, pt, &buf);
	}
	if (notypes)
		sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
	for (i = 0; i < notypes; ++i) {
		MonoReflectionType *pt;

		pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
		encode_reflection_type (assembly, pt, &buf);
	}

	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
	sigbuffer_free (&buf);
	return idx;
}

Project: mono
File: reflection.c

MonoType*
mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
{
	MonoClass *klass;
	MonoReflectionTypeBuilder *tb = NULL;
	gboolean is_dynamic = FALSE;
	MonoDomain *domain;
	MonoClass *geninst;

	mono_loader_lock ();

	domain = mono_object_domain (type);

	if (is_sre_type_builder (mono_object_class (type))) {
		tb = (MonoReflectionTypeBuilder *) type;

		is_dynamic = TRUE;
	} else if (is_sre_generic_instance (mono_object_class (type))) {
		MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
		MonoReflectionType *gtd = rgi->generic_type;

		if (is_sre_type_builder (mono_object_class (gtd))) {
			tb = (MonoReflectionTypeBuilder *)gtd;
			is_dynamic = TRUE;
		}
	}

	/* FIXME: fix the CreateGenericParameters protocol to avoid the two stage setup of TypeBuilders */
	if (tb && tb->generic_container)
		mono_reflection_create_generic_class (tb);

	klass = mono_class_from_mono_type (mono_reflection_type_get_handle (type));
	if (!klass->generic_container) {
		mono_loader_unlock ();
		return NULL;
	}

	if (klass->wastypebuilder) {
		tb = (MonoReflectionTypeBuilder *) mono_class_get_ref_info (klass);

		is_dynamic = TRUE;
	}

	mono_loader_unlock ();

	geninst = mono_class_bind_generic_parameters (klass, type_argc, types, is_dynamic);

	return &geninst->byval_arg;

Project: mono
File: reflection.c

compare_interface_impl (const void *a, const void *b)
{
	const guint32 *a_values = a;
	const guint32 *b_values = b;

	int klass = a_values [MONO_INTERFACEIMPL_CLASS] - b_values [MONO_INTERFACEIMPL_CLASS];
	if (klass)
		return klass;

	return a_values [MONO_INTERFACEIMPL_INTERFACE] - b_values [MONO_INTERFACEIMPL_INTERFACE];
}

Project: mono
File: reflection.c

mymono_metadata_type_hash (MonoType *t1)
{
	guint hash;

	hash = t1->type;

	hash |= t1->byref << 6; /* do not collide with t1->type values */
	switch (t1->type) {
	case MONO_TYPE_VALUETYPE:
	case MONO_TYPE_CLASS:
	case MONO_TYPE_SZARRAY:
		/* check if the distribution is good enough */
		return ((hash << 5) - hash) ^ mono_aligned_addr_hash (t1->data.klass);
	case MONO_TYPE_PTR:
		return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type);
	case MONO_TYPE_GENERICINST: {
		int i;
		MonoGenericInst *inst = t1->data.generic_class->context.class_inst;
		hash += g_str_hash (t1->data.generic_class->container_class->name);
		hash *= 13;
		for (i = 0; i < inst->type_argc; ++i) {
			hash += mymono_metadata_type_hash (inst->type_argv [i]);
			hash *= 13;
		}
		return hash;
	}
	case MONO_TYPE_VAR:
	case MONO_TYPE_MVAR:
		return ((hash << 5) - hash) ^ GPOINTER_TO_UINT (t1->data.generic_param);
	}
	return hash;
}

Project: mono
File: verify.c

do_sizeof (VerifyContext *ctx, int token)
{
	MonoType *type;

	if (!IS_TYPE_DEF_OR_REF_OR_SPEC (token) || !token_bounds_check (ctx->image, token)) {
		ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid type token %x at 0x%04x", token, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
		return;
	}
	
	if (!(type = verifier_load_type (ctx, token, "sizeof")))
		return;

	if (type->byref && type->type != MONO_TYPE_TYPEDBYREF) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid use of byref type at 0x%04x", ctx->ip_offset));
		return;
	}

	if (type->type == MONO_TYPE_VOID) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid use of void type at 0x%04x", ctx->ip_offset));
		return;
	}

	if (check_overflow (ctx))
		set_stack_value (ctx, stack_push (ctx), &mono_defaults.uint32_class->byval_arg, FALSE);
}

Project: mono
File: reflection.c

void
mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
{
	MonoError error;
	MonoClass *klass, *parent;

	MONO_ARCH_SAVE_REGS;

	RESOLVE_TYPE (tb->parent);

	mono_loader_lock ();

	if (tb->parent) {
		/* check so we can compile corlib correctly */
		if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
			/* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
			parent = mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent)->data.klass;
		} else {
			parent = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb->parent));
		}
	} else {
		parent = NULL;
	}
	
	/* the type has already being created: it means we just have to change the parent */
	if (tb->type.type) {
		klass = mono_class_from_mono_type (tb->type.type);
		klass->parent = NULL;
		/* fool mono_class_setup_parent */
		klass->supertypes = NULL;
		mono_class_setup_parent (klass, parent);
		mono_class_setup_mono_type (klass);
		mono_loader_unlock ();
		return;
	}

	klass = mono_image_alloc0 (&tb->module->dynamic_image->image, sizeof (MonoClass));

	klass->image = &tb->module->dynamic_image->image;

	klass->inited = 1; /* we lie to the runtime */
	klass->name = mono_string_to_utf8_image (klass->image, tb->name, &error);
	if (!mono_error_ok (&error))
		goto failure;
	klass->name_space = mono_string_to_utf8_image (klass->image, tb->nspace, &error);
	if (!mono_error_ok (&error))
		goto failure;
	klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
	klass->flags = tb->attrs;
	
	mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);

	klass->element_class = klass;

	if (mono_class_get_ref_info (klass) == NULL) {

		mono_class_set_ref_info (klass, tb);

		/* Put into cache so mono_class_get () will find it.
		Skip nested types as those should not be available on the global scope. */
		if (!tb->nesting_type) {
			mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
		} else {
			klass->image->reflection_info_unregister_classes =
				g_slist_prepend (klass->image->reflection_info_unregister_classes, klass);
		}
	} else {
		g_assert (mono_class_get_ref_info (klass) == tb);
	}

	mono_g_hash_table_insert (tb->module->dynamic_image->tokens,
		GUINT_TO_POINTER (MONO_TOKEN_TYPE_DEF | tb->table_idx), tb);

	if (parent != NULL) {
		mono_class_setup_parent (klass, parent);
	} else if (strcmp (klass->name, "Object") == 0 && strcmp (klass->name_space, "System") == 0) {
		const char *old_n = klass->name;
		/* trick to get relative numbering right when compiling corlib */
		klass->name = "BuildingObject";
		mono_class_setup_parent (klass, mono_defaults.object_class);
		klass->name = old_n;
	}

	if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
			(!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
			(!strcmp (klass->name, "Enum") && !strcmp (klass->name_space, "System"))) {
		klass->instance_size = sizeof (MonoObject);
		klass->size_inited = 1;
		mono_class_setup_vtable_general (klass, NULL, 0);
	}

	mono_class_setup_mono_type (klass);

	mono_class_setup_supertypes (klass);

	/*
	 * FIXME: handle interfaces.
	 */

	tb->type.type = &klass->byval_arg;

	if (tb->nesting_type) {
		g_assert (tb->nesting_type->type);
		klass->nested_in = mono_class_from_mono_type (mono_reflection_type_get_handle (tb->nesting_type));
	}

	/*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/

	mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
	
	mono_loader_unlock ();
	return;

failure:
	mono_loader_unlock ();
	mono_error_raise_exception (&error);

Project: mono
File: verify.c

do_ldlen (VerifyContext *ctx)
{
	ILStackDesc *value;

	if (!check_underflow (ctx, 1))
		return;

	value = stack_pop (ctx);

	if (stack_slot_get_type (value) != TYPE_COMPLEX || value->type->type != MONO_TYPE_SZARRAY)
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid array type for ldlen at 0x%04x", ctx->ip_offset));

	stack_push_val (ctx, TYPE_NATIVE_INT, &mono_defaults.int_class->byval_arg);	
}

Project: mono
File: reflection.c

load_public_key (MonoArray *pkey, MonoDynamicImage *assembly) {
	gsize len;
	guint32 token = 0;
	char blob_size [6];
	char *b = blob_size;

	if (!pkey)
		return token;

	len = mono_array_length (pkey);
	mono_metadata_encode_value (len, b, &b);
	token = mono_image_add_stream_data (&assembly->blob, blob_size, b - blob_size);
	mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, char, 0), len);

	assembly->public_key = g_malloc (len);
	memcpy (assembly->public_key, mono_array_addr (pkey, char, 0), len);
	assembly->public_key_len = len;

	/* Special case: check for ECMA key (16 bytes) */
	if ((len == MONO_ECMA_KEY_LENGTH) && mono_is_ecma_key (mono_array_addr (pkey, char, 0), len)) {
		/* In this case we must reserve 128 bytes (1024 bits) for the signature */
		assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH;
	} else if (len >= MONO_PUBLIC_KEY_HEADER_LENGTH + MONO_MINIMUM_PUBLIC_KEY_LENGTH) {
		/* minimum key size (in 2.0) is 384 bits */
		assembly->strong_name_size = len - MONO_PUBLIC_KEY_HEADER_LENGTH;
	} else {
		/* FIXME - verifier */
		g_warning ("Invalid public key length: %d bits (total: %d)", (int)MONO_PUBLIC_KEY_BIT_SIZE (len), (int)len);
		assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH; /* to be safe */
	}
	assembly->strong_name = g_malloc0 (assembly->strong_name_size);

	return token;
}

Project: mono
File: reflection.c

checked_write_file (HANDLE f, gconstpointer buffer, guint32 numbytes)
{
	guint32 dummy;
	if (!WriteFile (f, buffer, numbytes, &dummy, NULL))
		g_error ("WriteFile returned %d\n", GetLastError ());
}

Project: mono
File: verify.c

dump_stack_value (ILStackDesc *value)
{
	printf ("[(%x)(%x)", value->type->type, value->stype);

	if (stack_slot_is_this_pointer (value))
		printf ("[this] ");

	if (stack_slot_is_boxed_value (value))
		printf ("[boxed] ");

	if (stack_slot_is_null_literal (value))
		printf ("[null] ");

	if (stack_slot_is_managed_mutability_pointer (value))
		printf ("Controled Mutability MP: ");

	if (stack_slot_is_managed_pointer (value))
		printf ("Managed Pointer to: ");

	switch (stack_slot_get_underlying_type (value)) {
		case TYPE_INV:
			printf ("invalid type]"); 
			return;
		case TYPE_I4:
			printf ("int32]"); 
			return;
		case TYPE_I8:
			printf ("int64]"); 
			return;
		case TYPE_NATIVE_INT:
			printf ("native int]"); 
			return;
		case TYPE_R8:
			printf ("float64]"); 
			return;
		case TYPE_PTR:
			printf ("unmanaged pointer]"); 
			return;
		case TYPE_COMPLEX:
			switch (value->type->type) {
			case MONO_TYPE_CLASS:
			case MONO_TYPE_VALUETYPE:
				printf ("complex] (%s)", value->type->data.klass->name);
				return;
			case MONO_TYPE_STRING:
				printf ("complex] (string)");
				return;
			case MONO_TYPE_OBJECT:
				printf ("complex] (object)");
				return;
			case MONO_TYPE_SZARRAY:
				printf ("complex] (%s [])", value->type->data.klass->name);
				return;
			case MONO_TYPE_ARRAY:
				printf ("complex] (%s [%d %d %d])",
					value->type->data.array->eklass->name,
					value->type->data.array->rank,
					value->type->data.array->numsizes,
					value->type->data.array->numlobounds);
				return;
			case MONO_TYPE_GENERICINST:
				printf ("complex] (inst of %s )", value->type->data.generic_class->container_class->name);
				return;
			case MONO_TYPE_VAR:
				printf ("complex] (type generic param !%d - %s) ", value->type->data.generic_param->num, mono_generic_param_info (value->type->data.generic_param)->name);
				return;
			case MONO_TYPE_MVAR:
				printf ("complex] (method generic param !!%d - %s) ", value->type->data.generic_param->num, mono_generic_param_info (value->type->data.generic_param)->name);
				return;
			default: {
				//should be a boxed value 
				char * name = mono_type_full_name (value->type);
				printf ("complex] %s", name);
				g_free (name);
				return;
				}
			}
		default:
			printf ("unknown stack %x type]\n", value->stype);
			g_assert_not_reached ();
	}
}

Project: mono
File: verify.c

recursive_boxed_constraint_type_check (VerifyContext *ctx, MonoType *type, MonoClass *constraint_class, int recursion_level)
{
	MonoType *constraint_type = &constraint_class->byval_arg;
	if (recursion_level <= 0)
		return FALSE;

	if (verify_type_compatibility_full (ctx, type, mono_type_get_type_byval (constraint_type), FALSE))
		return TRUE;

	if (mono_type_is_generic_argument (constraint_type)) {
		MonoGenericParam *param = get_generic_param (ctx, constraint_type);
		MonoClass **class;
		if (!param)
			return FALSE;
		for (class = mono_generic_param_info (param)->constraints; class && *class; ++class) {
			if (recursive_boxed_constraint_type_check (ctx, type, *class, recursion_level - 1))
				return TRUE;
		}
	}
	return FALSE;
}

Project: mono
File: reflection.c

mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs)
{
	MonoDynamicTable *table;
	MonoReflectionCustomAttr *cattr;
	guint32 *values;
	guint32 count, i, token;
	char blob_size [6];
	char *p = blob_size;
	
	/* it is legal to pass a NULL cattrs: we avoid to use the if in a lot of places */
	if (!cattrs)
		return;
	count = mono_array_length (cattrs);
	table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
	table->rows += count;
	alloc_table (table, table->rows);
	values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
	idx <<= MONO_CUSTOM_ATTR_BITS;
	idx |= type;
	for (i = 0; i < count; ++i) {
		cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
		values [MONO_CUSTOM_ATTR_PARENT] = idx;
		token = mono_image_create_token (assembly, (MonoObject*)cattr->ctor, FALSE, FALSE);
		type = mono_metadata_token_index (token);
		type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
		switch (mono_metadata_token_table (token)) {
		case MONO_TABLE_METHOD:
			type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
			break;
		case MONO_TABLE_MEMBERREF:
			type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
			break;
		default:
			g_warning ("got wrong token in custom attr");
			continue;
		}
		values [MONO_CUSTOM_ATTR_TYPE] = type;
		p = blob_size;
		mono_metadata_encode_value (mono_array_length (cattr->data), p, &p);
		values [MONO_CUSTOM_ATTR_VALUE] = add_to_blob_cached (assembly, blob_size, p - blob_size,
			mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
		values += MONO_CUSTOM_ATTR_SIZE;
		++table->next_idx;
	}
}

Project: mono
File: reflection.c

guint32
mono_declsec_flags_from_assembly (MonoAssembly *assembly)
{
	guint32 idx = 1; /* there is only one assembly */
	idx <<= MONO_HAS_DECL_SECURITY_BITS;
	idx |= MONO_HAS_DECL_SECURITY_ASSEMBLY;
	return mono_declsec_get_flags (assembly->image, idx);

Project: mono
File: verify.c

verifier_load_type (VerifyContext *ctx, int token, const char *opcode) {
	MonoType* type;
	
	if (!IS_TYPE_DEF_OR_REF_OR_SPEC (token) || !token_bounds_check (ctx->image, token)) {
		ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid type token 0x%08x at 0x%04x", token, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
		return NULL;
	}

	type = mono_type_get_full (ctx->image, token, ctx->generic_context);

	if (!type || mono_loader_get_last_error ()) {
		ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Cannot load type from token 0x%08x for %s at 0x%04x", token, opcode, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
		mono_loader_clear_error ();
		return NULL;
	}

	if (!mono_type_is_valid_in_context (ctx, type))
		return NULL;

	return type;
}

Project: mono
File: verify.c

mono_class_has_default_constructor (MonoClass *klass)
{
	MonoMethod *method;
	int i;

	mono_class_setup_methods (klass);
	if (klass->exception_type)
		return FALSE;

	for (i = 0; i < klass->method.count; ++i) {
		method = klass->methods [i];
		if (mono_method_is_constructor (method) &&
			mono_method_signature (method) &&
			mono_method_signature (method)->param_count == 0 &&
			(method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)
			return TRUE;
	}
	return FALSE;
}

Project: mono
File: verify.c

do_unbox_value (VerifyContext *ctx, int klass_token)
{
	ILStackDesc *value;
	MonoType *type = get_boxable_mono_type (ctx, klass_token, "unbox");

	if (!type)
		return;
 
	if (!check_underflow (ctx, 1))
		return;

	if (!mono_class_from_mono_type (type)->valuetype)
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid reference type for unbox at 0x%04x", ctx->ip_offset));

	value = stack_pop (ctx);

	/*Value should be: a boxed valuetype or a reference type*/
	if (!(stack_slot_get_type (value) == TYPE_COMPLEX &&
		(stack_slot_is_boxed_value (value) || !mono_class_from_mono_type (value->type)->valuetype)))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type %s at stack for unbox operation at 0x%04x", stack_slot_get_name (value), ctx->ip_offset));

	set_stack_value (ctx, value = stack_push (ctx), mono_type_get_type_byref (type), FALSE);
	value->stype |= CMMP_MASK;
}

Project: mono
File: verify.c

is_clause_nested (MonoExceptionClause *clause, MonoExceptionClause *nested)
{
	if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER && is_clause_inside_range (nested, clause->data.filter_offset, clause->handler_offset))
		return TRUE;
	return is_clause_inside_range (nested, clause->try_offset, clause->try_offset + clause->try_len) ||
	is_clause_inside_range (nested, clause->handler_offset, clause->handler_offset + clause->handler_len);
}

Project: mono
File: reflection.c

mono_image_module_basic_init (MonoReflectionModuleBuilder *moduleb)
{
	MonoDynamicImage *image = moduleb->dynamic_image;
	MonoReflectionAssemblyBuilder *ab = moduleb->assemblyb;
	if (!image) {
		MonoError error;
		int module_count;
		MonoImage **new_modules;
		MonoImage *ass;
		char *name, *fqname;
		/*
		 * FIXME: we already created an image in mono_image_basic_init (), but
		 * we don't know which module it belongs to, since that is only 
		 * determined at assembly save time.
		 */
		/*image = (MonoDynamicImage*)ab->dynamic_assembly->assembly.image; */
		name = mono_string_to_utf8 (ab->name);
		fqname = mono_string_to_utf8_checked (moduleb->module.fqname, &error);
		if (!mono_error_ok (&error)) {
			g_free (name);
			mono_error_raise_exception (&error);
		}
		image = create_dynamic_mono_image (ab->dynamic_assembly, name, fqname);

		moduleb->module.image = &image->image;
		moduleb->dynamic_image = image;
		register_module (mono_object_domain (moduleb), moduleb, image);

		/* register the module with the assembly */
		ass = ab->dynamic_assembly->assembly.image;
		module_count = ass->module_count;
		new_modules = g_new0 (MonoImage *, module_count + 1);

		if (ass->modules)
			memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
		new_modules [module_count] = &image->image;
		mono_image_addref (&image->image);

		g_free (ass->modules);
		ass->modules = new_modules;
		ass->module_count ++;
	}
}

Project: mono
File: reflection.c

static gboolean
is_sr_mono_property (MonoClass *class)
{
	check_corlib_type_cached (class, "System.Reflection", "MonoProperty");

Project: mono
File: verify.c

verifier_inflate_type (VerifyContext *ctx, MonoType *type, MonoGenericContext *context)
{
	MonoError error;
	MonoType *result;

	result = mono_class_inflate_generic_type_checked (type, context, &error);
	if (!mono_error_ok (&error)) {
		mono_error_cleanup (&error);
		return NULL;
	}
	return result;
}

Project: mono
File: verify.c

mono_type_get_stack_name (MonoType *type)
{
	return type_names [get_stack_type (type) & TYPE_MASK];
}

Project: mono
File: verify.c

verify_clause_relationship (VerifyContext *ctx, MonoExceptionClause *clause, MonoExceptionClause *to_test)
{
	/*clause is nested*/
	if (to_test->flags == MONO_EXCEPTION_CLAUSE_FILTER && is_clause_inside_range (clause, to_test->data.filter_offset, to_test->handler_offset)) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Exception clause inside filter"));
		return;
	}

	/*wrong nesting order.*/
	if (is_clause_nested (clause, to_test)) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Nested exception clause appears after enclosing clause"));
		return;
	}

	/*mutual protection*/
	if (clause->try_offset == to_test->try_offset && clause->try_len == to_test->try_len) {
		/*handlers are not disjoint*/
		if (is_clause_in_range (to_test, HANDLER_START (clause), clause->handler_offset + clause->handler_len)) {
			ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Exception handlers overlap"));
			return;
		}
		/* handlers are not catch or filter */
		if (!IS_CATCH_OR_FILTER (clause) || !IS_CATCH_OR_FILTER (to_test)) {
			ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Exception clauses with shared protected block are neither catch or filter"));
			return;
		}
		/*OK*/
		return;
	}

	/*not completelly disjoint*/
	if ((is_clause_in_range (to_test, clause->try_offset, clause->try_offset + clause->try_len) ||
		is_clause_in_range (to_test, HANDLER_START (clause), clause->handler_offset + clause->handler_len)) && !is_clause_nested (to_test, clause))
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Exception clauses overlap"));
}

Project: mono
File: verify.c

ensure_stack_size (ILCodeDesc *stack, int required)
{
	int new_size = 8;
	ILStackDesc *tmp;

	if (required < stack->max_size)
		return;

	/* We don't have to worry about the exponential growth since stack_copy prune unused space */
	new_size = MAX (8, MAX (required, stack->max_size * 2));

	g_assert (new_size >= stack->size);
	g_assert (new_size >= required);

	tmp = g_new0 (ILStackDesc, new_size);
	MEM_ALLOC (sizeof (ILStackDesc) * new_size);

	if (stack->stack) {
		if (stack->size)
			memcpy (tmp, stack->stack, stack->size * sizeof (ILStackDesc));
		g_free (stack->stack);
		MEM_FREE (sizeof (ILStackDesc) * stack->max_size);
	}

	stack->stack = tmp;
	stack->max_size = new_size;
}

Project: mono
File: reflection.c

type_get_fully_qualified_name (MonoType *type)
{
	return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
}

Project: mono
File: verify.c

is_valid_generic_instantiation_in_context (VerifyContext *ctx, MonoGenericInst *ginst)
{
	int i;
	for (i = 0; i < ginst->type_argc; ++i) {
		MonoType *type = ginst->type_argv [i];
		if (!is_valid_type_in_context (ctx, type))
			return FALSE;
	}
	return TRUE;
}

Project: mono
File: reflection.c

create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
{
	const char *p = (const char*)data;
	const char *named;
	guint32 i, j, num_named;
	MonoObject *attr;
	void *params_buf [32];
	void **params;
	MonoMethodSignature *sig;

	mono_class_init (method->klass);

	if (!mono_verifier_verify_cattr_content (image, method, data, len, NULL))
		return NULL;

	if (len == 0) {
		attr = mono_object_new (mono_domain_get (), method->klass);
		mono_runtime_invoke (method, attr, NULL, NULL);
		return attr;
	}

	if (len < 2 || read16 (p) != 0x0001) /* Prolog */
		return NULL;

	/*g_print ("got attr %s\n", method->klass->name);*/

	sig = mono_method_signature (method);
	if (sig->param_count < 32)
		params = params_buf;
	else
		/* Allocate using GC so it gets GC tracking */
		params = mono_gc_alloc_fixed (sig->param_count * sizeof (void*), NULL);

	/* skip prolog */
	p += 2;
	for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
		params [i] = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p);
	}

	named = p;
	attr = mono_object_new (mono_domain_get (), method->klass);
	mono_runtime_invoke (method, attr, params, NULL);
	free_param_data (method->signature, params);
	num_named = read16 (named);
	named += 2;
	for (j = 0; j < num_named; j++) {
		gint name_len;
		char *name, named_type, data_type;
		named_type = *named++;
		data_type = *named++; /* type of data */
		if (data_type == MONO_TYPE_SZARRAY)
			data_type = *named++;
		if (data_type == MONO_TYPE_ENUM) {
			gint type_len;
			char *type_name;
			type_len = mono_metadata_decode_blob_size (named, &named);
			type_name = g_malloc (type_len + 1);
			memcpy (type_name, named, type_len);
			type_name [type_len] = 0;
			named += type_len;
			/* FIXME: lookup the type and check type consistency */
			g_free (type_name);
		}
		name_len = mono_metadata_decode_blob_size (named, &named);
		name = g_malloc (name_len + 1);
		memcpy (name, named, name_len);
		name [name_len] = 0;
		named += name_len;
		if (named_type == 0x53) {
			MonoClassField *field = mono_class_get_field_from_name (mono_object_class (attr), name);
			void *val = load_cattr_value (image, field->type, named, &named);
			mono_field_set_value (attr, field, val);
			if (!type_is_reference (field->type))
				g_free (val);
		} else if (named_type == 0x54) {
			MonoProperty *prop;
			void *pparams [1];
			MonoType *prop_type;

			prop = mono_class_get_property_from_name (mono_object_class (attr), name);
			/* can we have more that 1 arg in a custom attr named property? */
			prop_type = prop->get? mono_method_signature (prop->get)->ret :
			     mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
			pparams [0] = load_cattr_value (image, prop_type, named, &named);
			mono_property_set_value (prop, attr, pparams, NULL);
			if (!type_is_reference (prop_type))
				g_free (pparams [0]);
		}
		g_free (name);
	}

	if (params != params_buf)
		mono_gc_free_fixed (params);

	return attr;
}

Project: mono
File: reflection.c

MonoArray*
mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues) 
{
	MonoArray *result;
	MonoMethodSignature *sig;
	MonoObject *arg;
	char *buffer, *p;
	guint32 buflen, i;

	MONO_ARCH_SAVE_REGS;

	if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
		/* sig is freed later so allocate it in the heap */
		sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor);
	} else {
		sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
	}

	g_assert (mono_array_length (ctorArgs) == sig->param_count);
	buflen = 256;
	p = buffer = g_malloc (buflen);
	/* write the prolog */
	*p++ = 1;
	*p++ = 0;
	for (i = 0; i < sig->param_count; ++i) {
		arg = mono_array_get (ctorArgs, MonoObject*, i);
		encode_cattr_value (assembly->assembly, buffer, p, &buffer, &p, &buflen, sig->params [i], arg, NULL);
	}
	i = 0;
	if (properties)
		i += mono_array_length (properties);
	if (fields)
		i += mono_array_length (fields);
	*p++ = i & 0xff;
	*p++ = (i >> 8) & 0xff;
	if (properties) {
		MonoObject *prop;
		for (i = 0; i < mono_array_length (properties); ++i) {
			MonoType *ptype;
			char *pname;

			prop = mono_array_get (properties, gpointer, i);
			get_prop_name_and_type (prop, &pname, &ptype);
			*p++ = 0x54; /* PROPERTY signature */
			encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ptype, pname, (MonoObject*)mono_array_get (propValues, gpointer, i));
			g_free (pname);
		}
	}

	if (fields) {
		MonoObject *field;
		for (i = 0; i < mono_array_length (fields); ++i) {
			MonoType *ftype;
			char *fname;

			field = mono_array_get (fields, gpointer, i);
			get_field_name_and_type (field, &fname, &ftype);
			*p++ = 0x53; /* FIELD signature */
			encode_named_val (assembly, buffer, p, &buffer, &p, &buflen, ftype, fname, (MonoObject*)mono_array_get (fieldValues, gpointer, i));
			g_free (fname);
		}
	}

	g_assert (p - buffer <= buflen);
	buflen = p - buffer;
	result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, buflen);
	p = mono_array_addr (result, char, 0);
	memcpy (p, buffer, buflen);
	g_free (buffer);
	if (strcmp (ctor->vtable->klass->name, "MonoCMethod"))
		g_free (sig);
	return result;

Project: mono
File: verify.c

stack_pop (VerifyContext *ctx)
{
	ILStackDesc *ret;
	g_assert (ctx->eval.size > 0);	
	ret = ctx->eval.stack + --ctx->eval.size;
	if ((ret->stype & UNINIT_THIS_MASK) == UNINIT_THIS_MASK)
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Found use of uninitialized 'this ptr' ref at 0x%04x", ctx->ip_offset));
	return ret;
}

Project: mono
File: reflection.c

MonoType*
mono_reflection_type_get_handle (MonoReflectionType* ref)
{
	MonoClass *class;
	if (!ref)
		return NULL;
	if (ref->type)
		return ref->type;

	if (is_usertype (ref)) {
		ref = mono_reflection_type_get_underlying_system_type (ref);
		if (ref == NULL || is_usertype (ref))
			return NULL;
		if (ref->type)
			return ref->type;
	}

	class = mono_object_class (ref);

	if (is_sre_array (class)) {
		MonoType *res;
		MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
		MonoType *base = mono_reflection_type_get_handle (sre_array->element_type);
		g_assert (base);
		if (sre_array->rank == 0) //single dimentional array
			res = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
		else
			res = &mono_bounded_array_class_get (mono_class_from_mono_type (base), sre_array->rank, TRUE)->byval_arg;
		sre_array->type.type = res;
		return res;
	} else if (is_sre_byref (class)) {
		MonoType *res;
		MonoReflectionDerivedType *sre_byref = (MonoReflectionDerivedType*)ref;
		MonoType *base = mono_reflection_type_get_handle (sre_byref->element_type);
		g_assert (base);
		res = &mono_class_from_mono_type (base)->this_arg;
		sre_byref->type.type = res;
		return res;
	} else if (is_sre_pointer (class)) {
		MonoType *res;
		MonoReflectionDerivedType *sre_pointer = (MonoReflectionDerivedType*)ref;
		MonoType *base = mono_reflection_type_get_handle (sre_pointer->element_type);
		g_assert (base);
		res = &mono_ptr_class_get (base)->byval_arg;
		sre_pointer->type.type = res;
		return res;
	} else if (is_sre_generic_instance (class)) {
		MonoType *res, **types;
		MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)ref;
		int i, count;

		count = mono_array_length (gclass->type_arguments);
		types = g_new0 (MonoType*, count);
		for (i = 0; i < count; ++i) {
			MonoReflectionType *t = mono_array_get (gclass->type_arguments, gpointer, i);
			types [i] = mono_reflection_type_get_handle (t);
			if (!types[i]) {
				g_free (types);
				return NULL;
			}
		}

		res = mono_reflection_bind_generic_parameters (gclass->generic_type, count, types);
		g_free (types);
		g_assert (res);
		gclass->type.type = res;
		return res;
	}

	g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
	return NULL;

Project: mono
File: reflection.c

static gboolean
is_usertype (MonoReflectionType *ref)
{
	MonoClass *class = mono_object_class (ref);
	return class->image != mono_defaults.corlib || strcmp ("TypeDelegator", class->name) == 0;

Project: mono
File: reflection.c

clear_cached_object (MonoDomain *domain, gpointer o, MonoClass *klass)
{
	mono_domain_lock (domain);
	if (domain->refobject_hash) {
        ReflectedEntry pe;
		gpointer orig_pe, orig_value;

		pe.item = o;
		pe.refclass = klass;
		if (mono_g_hash_table_lookup_extended (domain->refobject_hash, &pe, &orig_pe, &orig_value)) {
			mono_g_hash_table_remove (domain->refobject_hash, &pe);
			FREE_REFENTRY (orig_pe);
		}
	}
	mono_domain_unlock (domain);
}

Project: mono
File: reflection.c

mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
{
	MonoArray *result;
	MonoCustomAttrInfo *cinfo;

	cinfo = mono_reflection_get_custom_attrs_info (obj);
	if (cinfo) {
		if (attr_klass)
			result = mono_custom_attrs_construct_by_type (cinfo, attr_klass);
		else
			result = mono_custom_attrs_construct (cinfo);
		if (!cinfo->cached)
			mono_custom_attrs_free (cinfo);
	} else {
		if (mono_loader_get_last_error ())
			return NULL;
		result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0);
	}

	return result;
}

Project: mono
File: reflection.c

void
mono_reflection_register_with_runtime (MonoReflectionType *type)
{
	MonoType *res = mono_reflection_type_get_handle (type);
	MonoDomain *domain = mono_object_domain ((MonoObject*)type);
	MonoClass *class;

	if (!res)
		mono_raise_exception (mono_get_exception_argument (NULL, "Invalid generic instantiation, one or more arguments are not proper user types"));

	class = mono_class_from_mono_type (res);

	mono_loader_lock (); /*same locking as mono_type_get_object*/
	mono_domain_lock (domain);

	if (!class->image->dynamic) {
		mono_class_setup_supertypes (class);
	} else {
		if (!domain->type_hash)
			domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash, 
					(GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
		mono_g_hash_table_insert (domain->type_hash, res, type);
	}
	mono_domain_unlock (domain);
	mono_loader_unlock ();

Project: mono
File: verify.c

GSList*
mono_method_verify_with_current_settings (MonoMethod *method, gboolean skip_visibility)
{
	return mono_method_verify (method, 
			(verifier_mode != MONO_VERIFIER_MODE_STRICT ? MONO_VERIFY_NON_STRICT: 0)
			| (!mono_verifier_is_method_full_trust (method) ? MONO_VERIFY_FAIL_FAST : 0)
			| (skip_visibility ? MONO_VERIFY_SKIP_VISIBILITY : 0));

Project: mono
File: verify.c

is_compatible_boxed_valuetype (VerifyContext *ctx, MonoType *type, MonoType *candidate, ILStackDesc *stack, gboolean strict)
{
	if (!stack_slot_is_boxed_value (stack))
		return FALSE;
	if (type->byref || candidate->byref)
		return FALSE;

	if (mono_type_is_generic_argument (candidate)) {
		MonoGenericParam *param = get_generic_param (ctx, candidate);
		MonoClass **class;
		if (!param)
			return FALSE;

		for (class = mono_generic_param_info (param)->constraints; class && *class; ++class) {
			/*256 should be enough since there can't be more than 255 generic arguments.*/
			if (recursive_boxed_constraint_type_check (ctx, type, *class, 256))
				return TRUE;
		}
	}

	if (mono_type_is_generic_argument (type))
		return FALSE;

	if (!strict)
		return TRUE;

	return MONO_TYPE_IS_REFERENCE (type) && mono_class_is_assignable_from (mono_class_from_mono_type (type), mono_class_from_mono_type (candidate));
}

Project: mono
File: reflection.c

mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
{
	guint32 idx;
	
	if (klass->image->dynamic) {
		property = mono_metadata_get_corresponding_property_from_generic_type_definition (property);
		return lookup_custom_attr (klass->image, property);
	}
	idx = find_property_index (klass, property);
	idx <<= MONO_CUSTOM_ATTR_BITS;
	idx |= MONO_CUSTOM_ATTR_PROPERTY;
	return mono_custom_attrs_from_index (klass->image, idx);
}

Project: mono
File: verify.c

static int
get_field_end (MonoClassField *field)
{
	int align;
	int size = mono_type_size (field->type, &align);
	if (size == 0)
		size = 4; /*FIXME Is this a safe bet?*/
	return size + field->offset;

Project: mono
File: verify.c

GSList*
mono_method_verify (MonoMethod *method, int level)
{
	/* The verifier was disabled at compile time */
	return NULL;

Project: mono
File: verify.c

verify_stack_type_compatibility (VerifyContext *ctx, MonoType *type, ILStackDesc *stack)
{
	return verify_stack_type_compatibility_full (ctx, type, stack, FALSE, FALSE);
}

Project: mono
File: reflection.c

mono_image_get_sighelper_token (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper)
{
	guint32 idx;
	MonoDynamicTable *table;
	guint32 *values;

	table = &assembly->tables [MONO_TABLE_STANDALONESIG];
	idx = table->next_idx ++;
	table->rows ++;
	alloc_table (table, table->rows);
	values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;

	values [MONO_STAND_ALONE_SIGNATURE] =
		mono_reflection_encode_sighelper (assembly, helper);

	return idx;
}

Project: mono
File: reflection.c

add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2)
{
	guint32 idx;
	char *copy;
	gpointer oldkey, oldval;

	copy = g_malloc (s1+s2);
	memcpy (copy, b1, s1);
	memcpy (copy + s1, b2, s2);
	if (g_hash_table_lookup_extended (assembly->blob_cache, copy, &oldkey, &oldval)) {
		g_free (copy);
		idx = GPOINTER_TO_UINT (oldval);
	} else {
		idx = mono_image_add_stream_data (&assembly->blob, b1, s1);
		mono_image_add_stream_data (&assembly->blob, b2, s2);
		g_hash_table_insert (assembly->blob_cache, copy, GUINT_TO_POINTER (idx));
	}
	return idx;
}

Project: mono
File: reflection.c

mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
{
	guint32 idx;
	
	make_room_in_stream (stream, stream->index + len);
	memcpy (stream->data + stream->index, data, len);
	idx = stream->index;
	stream->index += len;
	/* 
	 * align index? Not without adding an additional param that controls it since
	 * we may store a blob value in pieces.
	 */
	return idx;
}

Project: mono
File: reflection.c

free_blob_cache_entry (gpointer key, gpointer val, gpointer user_data)
{
	g_free (key);
}

Project: mono
File: verify.c

do_ret (VerifyContext *ctx)
{
	MonoType *ret = ctx->signature->ret;
	VERIFIER_DEBUG ( printf ("checking ret\n"); );
	if (ret->type != MONO_TYPE_VOID) {
		ILStackDesc *top;
		if (!check_underflow (ctx, 1))
			return;

		top = stack_pop(ctx);

		if (!verify_stack_type_compatibility (ctx, ctx->signature->ret, top)) {
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Incompatible return value on stack with method signature ret at 0x%04x", ctx->ip_offset));
			return;
		}

		if (ret->byref || ret->type == MONO_TYPE_TYPEDBYREF || mono_type_is_value_type (ret, "System", "ArgIterator") || mono_type_is_value_type (ret, "System", "RuntimeArgumentHandle"))
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Method returns byref, TypedReference, ArgIterator or RuntimeArgumentHandle at 0x%04x", ctx->ip_offset));
	}

	if (ctx->eval.size > 0) {
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Stack not empty (%d) after ret at 0x%04x", ctx->eval.size, ctx->ip_offset));
	} 
	if (in_any_block (ctx->header, ctx->ip_offset))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("ret cannot escape exception blocks at 0x%04x", ctx->ip_offset));
}

Project: mono
File: verify.c

set_stack_value (VerifyContext *ctx, ILStackDesc *stack, MonoType *type, int take_addr)
{
	int mask = 0;
	int type_kind = type->type;

	if (type->byref || take_addr)
		mask = POINTER_MASK;
	/* TODO handle CMMP_MASK */

handle_enum:
	stack->type = type;

	switch (type_kind) {
	case MONO_TYPE_I1:
	case MONO_TYPE_U1:
	case MONO_TYPE_BOOLEAN:
	case MONO_TYPE_I2:
	case MONO_TYPE_U2:
	case MONO_TYPE_CHAR:
	case MONO_TYPE_I4:
	case MONO_TYPE_U4:
		stack->stype = TYPE_I4 | mask;
		break;
	case MONO_TYPE_I:
	case MONO_TYPE_U:
		stack->stype = TYPE_NATIVE_INT | mask;
		break;

	/*FIXME: Do we need to check if it's a pointer to the method pointer? The spec says it' illegal to have that.*/
	case MONO_TYPE_FNPTR:
	case MONO_TYPE_PTR:
	case MONO_TYPE_TYPEDBYREF:
		stack->stype = TYPE_PTR | mask;
		break;

	case MONO_TYPE_CLASS:
	case MONO_TYPE_STRING:
	case MONO_TYPE_OBJECT:
	case MONO_TYPE_SZARRAY:
	case MONO_TYPE_ARRAY:

	case MONO_TYPE_VAR:
	case MONO_TYPE_MVAR: 
		stack->stype = TYPE_COMPLEX | mask;
		break;
		
	case MONO_TYPE_I8:
	case MONO_TYPE_U8:
		stack->stype = TYPE_I8 | mask;
		break;
	case MONO_TYPE_R4:
	case MONO_TYPE_R8:
		stack->stype = TYPE_R8 | mask;
		break;
	case MONO_TYPE_GENERICINST:
	case MONO_TYPE_VALUETYPE:
		if (mono_type_is_enum_type (type)) {
			MonoType *utype = mono_type_get_underlying_type_any (type);
			if (!utype) {
				ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Could not resolve underlying type of %x at %d", type->type, ctx->ip_offset));
				return FALSE;
			}
			type = utype;
			type_kind = type->type;
			goto handle_enum;
		} else {
			stack->stype = TYPE_COMPLEX | mask;
			break;
		}
	default:
		VERIFIER_DEBUG ( printf ("unknown type 0x%02x in eval stack type\n", type->type); );
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Illegal value set on stack 0x%02x at %d", type->type, ctx->ip_offset));
		return FALSE;
	}
	return TRUE;
}

Project: mono
File: reflection.c

static guint32
mono_declsec_get_flags (MonoImage *image, guint32 token)
{
	int index = mono_metadata_declsec_from_index (image, token);
	MonoTableInfo *t = &image->tables [MONO_TABLE_DECLSECURITY];
	guint32 result = 0;
	guint32 action;
	int i;

	/* HasSecurity can be present for other, not specially encoded, attributes,
	   e.g. SuppressUnmanagedCodeSecurityAttribute */
	if (index < 0)
		return 0;

	for (i = index; i < t->rows; i++) {
		guint32 cols [MONO_DECL_SECURITY_SIZE];

		mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);
		if (cols [MONO_DECL_SECURITY_PARENT] != token)
			break;

		action = cols [MONO_DECL_SECURITY_ACTION];
		if ((action >= MONO_DECLSEC_ACTION_MIN) && (action <= MONO_DECLSEC_ACTION_MAX)) {
			result |= declsec_flags_map [action];
		} else {
			g_assert_not_reached ();
		}
	}
	return result;

Project: mono
File: verify.c

do_stobj (VerifyContext *ctx, int token) 
{
	ILStackDesc *dest, *src;
	MonoType *type = get_boxable_mono_type (ctx, token, "stobj");
	CLEAR_PREFIX (ctx, PREFIX_UNALIGNED | PREFIX_VOLATILE);

	if (!type)
		return;

	if (!check_underflow (ctx, 2))
		return;

	src = stack_pop (ctx);
	dest = stack_pop (ctx);

	if (stack_slot_is_managed_mutability_pointer (dest))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use a readonly pointer with stobj at 0x%04x", ctx->ip_offset));

	if (!stack_slot_is_managed_pointer (dest)) 
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid destination of stobj operation at 0x%04x", ctx->ip_offset));

	if (stack_slot_is_boxed_value (src) && !MONO_TYPE_IS_REFERENCE (src->type) && !MONO_TYPE_IS_REFERENCE (type))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use stobj with a boxed source value that is not a reference type at 0x%04x", ctx->ip_offset));

	if (!verify_stack_type_compatibility (ctx, type, src)) {
		char *type_name = mono_type_full_name (type);
		char *src_name = stack_slot_full_name (src);
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Token '%s' and source '%s' of stobj don't match ' at 0x%04x", type_name, src_name, ctx->ip_offset));
		g_free (type_name);
		g_free (src_name);
	}

	if (!verify_type_compatibility (ctx, mono_type_get_type_byval (dest->type), type))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Destination and token types of stobj don't match at 0x%04x", ctx->ip_offset));
}

Project: mono
File: verify.c

is_correct_rethrow (MonoMethodHeader *header, guint offset)
{
	int i;
	MonoExceptionClause *clause;

	for (i = 0; i < header->num_clauses; ++i) {
		clause = &header->clauses [i];
		if (MONO_OFFSET_IN_HANDLER (clause, offset))
			return 1;
		if (MONO_OFFSET_IN_FILTER (clause, offset))
			return 1;
	}
	return 0;
}

Project: mono
File: reflection.c

mono_assembly_get_object (MonoDomain *domain, MonoAssembly *assembly)
{
	static MonoClass *assembly_type;
	MonoReflectionAssembly *res;
	
	CHECK_OBJECT (MonoReflectionAssembly *, assembly, NULL);
	if (!assembly_type) {
		MonoClass *class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoAssembly");
		if (class == NULL)
			class = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Assembly");
		g_assert (class);
		assembly_type = class;
	}
	res = (MonoReflectionAssembly *)mono_object_new (domain, assembly_type);
	res->assembly = assembly;

	CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
}

Project: mono
File: reflection.c

gboolean
mono_reflection_is_valid_dynamic_token (MonoDynamicImage *image, guint32 token)
{
	return mono_g_hash_table_lookup (image->tokens, GUINT_TO_POINTER (token)) != NULL;

Project: mono
File: verify.c

do_binop (VerifyContext *ctx, unsigned int opcode, const unsigned char table [TYPE_MAX][TYPE_MAX])
{
	ILStackDesc *a, *b, *top;
	int idxa, idxb, complexMerge = 0;
	unsigned char res;

	if (!check_underflow (ctx, 2))
		return;
	b = stack_pop (ctx);
	a = stack_pop (ctx);

	idxa = stack_slot_get_underlying_type (a);
	if (stack_slot_is_managed_pointer (a)) {
		idxa = TYPE_PTR;
		complexMerge = 1;
	}

	idxb = stack_slot_get_underlying_type (b);
	if (stack_slot_is_managed_pointer (b)) {
		idxb = TYPE_PTR;
		complexMerge = 2;
	}

	--idxa;
	--idxb;
	res = table [idxa][idxb];

	VERIFIER_DEBUG ( printf ("binop res %d\n", res); );
	VERIFIER_DEBUG ( printf ("idxa %d idxb %d\n", idxa, idxb); );

	top = stack_push (ctx);
	if (res == TYPE_INV) {
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Binary instruction applyed to ill formed stack (%s x %s)", stack_slot_get_name (a), stack_slot_get_name (b)));
		copy_stack_value (top, a);
		return;
	}

 	if (res & NON_VERIFIABLE_RESULT) {
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Binary instruction is not verifiable (%s x %s)", stack_slot_get_name (a), stack_slot_get_name (b)));

		res = res & ~NON_VERIFIABLE_RESULT;
 	}

 	if (complexMerge && res == TYPE_PTR) {
 		if (complexMerge == 1) 
 			copy_stack_value (top, a);
 		else if (complexMerge == 2)
 			copy_stack_value (top, b);
		/*
		 * There is no need to merge the type of two pointers.
		 * The only valid operation is subtraction, that returns a native
		 *  int as result and can be used with any 2 pointer kinds.
		 * This is valid acording to Patition III 1.1.4
		 */
 	} else
 		top->stype = res;
 	
}

Project: mono
File: reflection.c

mono_reflection_init (void)
{
}

Project: mono
File: verify.c

do_conversion (VerifyContext *ctx, int kind) 
{
	ILStackDesc *value;
	if (!check_underflow (ctx, 1))
		return;
	value = stack_pop (ctx);

	switch (stack_slot_get_type (value)) {
	case TYPE_I4:
	case TYPE_I8:
	case TYPE_NATIVE_INT:
	case TYPE_R8:
		break;
	default:
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type (%s) at stack for conversion operation. Numeric type expected at 0x%04x", stack_slot_get_name (value), ctx->ip_offset));
	}

	switch (kind) {
	case TYPE_I4:
		stack_push_val (ctx, TYPE_I4, &mono_defaults.int32_class->byval_arg);
		break;
	case TYPE_I8:
		stack_push_val (ctx,TYPE_I8, &mono_defaults.int64_class->byval_arg);
		break;
	case TYPE_R8:
		stack_push_val (ctx, TYPE_R8, &mono_defaults.double_class->byval_arg);
		break;
	case TYPE_NATIVE_INT:
		stack_push_val (ctx, TYPE_NATIVE_INT, &mono_defaults.int_class->byval_arg);
		break;
	default:
		g_error ("unknown type %02x in conversion", kind);

	}
}

Project: mono
File: reflection.c

sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
{
	char blob_size [8];
	char *b = blob_size;
	guint32 size = buf->p - buf->buf;
	/* store length */
	g_assert (size <= (buf->end - buf->buf));
	mono_metadata_encode_value (size, b, &b);
	return add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
}

Project: mono
File: reflection.c

mono_type_normalize (MonoType *type)
{
	int i;
	MonoGenericClass *gclass;
	MonoGenericInst *ginst;
	MonoClass *gtd;
	MonoGenericContainer *gcontainer;
	MonoType **argv = NULL;
	gboolean is_denorm_gtd = TRUE, requires_rebind = FALSE;

	if (type->type != MONO_TYPE_GENERICINST)
		return type;

	gclass = type->data.generic_class;
	ginst = gclass->context.class_inst;
	if (!ginst->is_open)
		return type;

	gtd = gclass->container_class;
	gcontainer = gtd->generic_container;
	argv = g_newa (MonoType*, ginst->type_argc);

	for (i = 0; i < ginst->type_argc; ++i) {
		MonoType *t = ginst->type_argv [i], *norm;
		if (t->type != MONO_TYPE_VAR || t->data.generic_param->num != i || t->data.generic_param->owner != gcontainer)
			is_denorm_gtd = FALSE;
		norm = mono_type_normalize (t);
		argv [i] = norm;
		if (norm != t)
			requires_rebind = TRUE;
	}

	if (is_denorm_gtd)
		return type->byref == gtd->byval_arg.byref ? &gtd->byval_arg : &gtd->this_arg;

	if (requires_rebind) {
		MonoClass *klass = mono_class_bind_generic_parameters (gtd, ginst->type_argc, argv, gclass->is_dynamic);
		return type->byref == klass->byval_arg.byref ? &klass->byval_arg : &klass->this_arg;
	}

	return type;
}

Project: mono
File: verify.c

gboolean
mono_verifier_is_enabled_for_class (MonoClass *klass)
{
	return verify_all || (verifier_mode > MONO_VERIFIER_MODE_OFF && !(klass->image->assembly && klass->image->assembly->in_gac) && klass->image != mono_defaults.corlib);

Project: mono
File: verify.c

verify_ldftn_delegate (VerifyContext *ctx, MonoClass *delegate, ILStackDesc *value, ILStackDesc *funptr)
{
	MonoMethod *method = funptr->method;

	/*ldftn non-final virtuals only allowed if method is not static,
	 * the object is a this arg (comes from a ldarg.0), and there is no starg.0.
	 * This rules doesn't apply if the object on stack is a boxed valuetype.
	 */
	if ((method->flags & METHOD_ATTRIBUTE_VIRTUAL) && !(method->flags & METHOD_ATTRIBUTE_FINAL) && !(method->klass->flags & TYPE_ATTRIBUTE_SEALED) && !stack_slot_is_boxed_value (value)) {
		/*A stdarg 0 must not happen, we fail here only in fail fast mode to avoid double error reports*/
		if (IS_FAIL_FAST_MODE (ctx) && ctx->has_this_store)
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid ldftn with virtual function in method with stdarg 0 at  0x%04x", ctx->ip_offset));

		/*current method must not be static*/
		if (ctx->method->flags & METHOD_ATTRIBUTE_STATIC)
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid ldftn with virtual function at 0x%04x", ctx->ip_offset));

		/*value is the this pointer, loaded using ldarg.0 */
		if (!stack_slot_is_this_pointer (value))
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid object argument, it is not the this pointer, to ldftn with virtual method at  0x%04x", ctx->ip_offset));

		ctx->code [ctx->ip_offset].flags |= IL_CODE_LDFTN_DELEGATE_NONFINAL_VIRTUAL;
	}
}

Project: mono
File: verify.c

store_local (VerifyContext *ctx, guint32 arg)
{
	ILStackDesc *value;
	if (arg >= ctx->num_locals) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Method doesn't have local var %d at 0x%04x", arg + 1, ctx->ip_offset));
		return;
	}

	/*TODO verify definite assigment */		
	if (check_underflow (ctx, 1)) {
		value = stack_pop(ctx);
		if (!verify_stack_type_compatibility (ctx, ctx->locals [arg], value)) {
			char *expected = mono_type_full_name (ctx->locals [arg]);
			char *found = stack_slot_full_name (value);
			CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Incompatible type '%s' on stack cannot be stored to local %d with type '%s' at 0x%04x",
					found,
					arg,
					expected,
					ctx->ip_offset));
			g_free (expected);
			g_free (found);	
		}
	}
}

Project: mono
File: verify.c

GSList*
mono_method_verify (MonoMethod *method, int level)
{
	MonoError error;
	const unsigned char *ip, *code_start;
	const unsigned char *end;
	MonoSimpleBasicBlock *bb = NULL, *original_bb = NULL;

	int i, n, need_merge = 0, start = 0;
	guint token, ip_offset = 0, prefix = 0;
	MonoGenericContext *generic_context = NULL;
	MonoImage *image;
	VerifyContext ctx;
	GSList *tmp;
	VERIFIER_DEBUG ( printf ("Verify IL for method %s %s %s\n",  method->klass->name_space,  method->klass->name, method->name); );

	init_verifier_stats ();

	if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME) ||
			(method->flags & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT))) {
		return NULL;
	}

	memset (&ctx, 0, sizeof (VerifyContext));

	//FIXME use mono_method_get_signature_full
	ctx.signature = mono_method_signature (method);
	if (!ctx.signature) {
		ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Could not decode method signature"));

		finish_collect_stats ();
		return ctx.list;
	}
	ctx.header = mono_method_get_header (method);
	if (!ctx.header) {
		ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Could not decode method header"));
		finish_collect_stats ();
		return ctx.list;
	}
	ctx.method = method;
	code_start = ip = ctx.header->code;
	end = ip + ctx.header->code_size;
	ctx.image = image = method->klass->image;


	ctx.max_args = ctx.signature->param_count + ctx.signature->hasthis;
	ctx.max_stack = ctx.header->max_stack;
	ctx.verifiable = ctx.valid = 1;
	ctx.level = level;

	ctx.code = g_new (ILCodeDesc, ctx.header->code_size);
	ctx.code_size = ctx.header->code_size;
	MEM_ALLOC (sizeof (ILCodeDesc) * ctx.header->code_size);

	memset(ctx.code, 0, sizeof (ILCodeDesc) * ctx.header->code_size);

	ctx.num_locals = ctx.header->num_locals;
	ctx.locals = g_memdup (ctx.header->locals, sizeof (MonoType*) * ctx.header->num_locals);
	MEM_ALLOC (sizeof (MonoType*) * ctx.header->num_locals);

	if (ctx.num_locals > 0 && !ctx.header->init_locals)
		CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Method with locals variable but without init locals set"));

	ctx.params = g_new (MonoType*, ctx.max_args);
	MEM_ALLOC (sizeof (MonoType*) * ctx.max_args);

	if (ctx.signature->hasthis)
		ctx.params [0] = method->klass->valuetype ? &method->klass->this_arg : &method->klass->byval_arg;
	memcpy (ctx.params + ctx.signature->hasthis, ctx.signature->params, sizeof (MonoType *) * ctx.signature->param_count);

	if (ctx.signature->is_inflated)
		ctx.generic_context = generic_context = mono_method_get_context (method);

	if (!generic_context && (method->klass->generic_container || method->is_generic)) {
		if (method->is_generic)
			ctx.generic_context = generic_context = &(mono_method_get_generic_container (method)->context);
		else
			ctx.generic_context = generic_context = &method->klass->generic_container->context;
	}

	for (i = 0; i < ctx.num_locals; ++i) {
		MonoType *uninflated = ctx.locals [i];
		ctx.locals [i] = mono_class_inflate_generic_type_checked (ctx.locals [i], ctx.generic_context, &error);
		if (!mono_error_ok (&error)) {
			char *name = mono_type_full_name (ctx.locals [i] ? ctx.locals [i] : uninflated);
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid local %d of type %s", i, name));
			g_free (name);
			mono_error_cleanup (&error);
			/* we must not free (in cleanup) what was not yet allocated (but only copied) */
			ctx.num_locals = i;
			ctx.max_args = 0;
			goto cleanup;
		}
	}
	for (i = 0; i < ctx.max_args; ++i) {
		MonoType *uninflated = ctx.params [i];
		ctx.params [i] = mono_class_inflate_generic_type_checked (ctx.params [i], ctx.generic_context, &error);
		if (!mono_error_ok (&error)) {
			char *name = mono_type_full_name (ctx.params [i] ? ctx.params [i] : uninflated);
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid parameter %d of type %s", i, name));
			g_free (name);
			mono_error_cleanup (&error);
			/* we must not free (in cleanup) what was not yet allocated (but only copied) */
			ctx.max_args = i;
			goto cleanup;
		}
	}
	stack_init (&ctx, &ctx.eval);

	for (i = 0; i < ctx.num_locals; ++i) {
		if (!mono_type_is_valid_in_context (&ctx, ctx.locals [i]))
			break;
		if (get_stack_type (ctx.locals [i]) == TYPE_INV) {
			char *name = mono_type_full_name (ctx.locals [i]);
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid local %i of type %s", i, name));
			g_free (name);
			break;
		}
		
	}

	for (i = 0; i < ctx.max_args; ++i) {
		if (!mono_type_is_valid_in_context (&ctx, ctx.params [i]))
			break;

		if (get_stack_type (ctx.params [i]) == TYPE_INV) {
			char *name = mono_type_full_name (ctx.params [i]);
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid parameter %i of type %s", i, name));
			g_free (name);
			break;
		}
	}

	if (!ctx.valid)
		goto cleanup;

	for (i = 0; i < ctx.header->num_clauses && ctx.valid; ++i) {
		MonoExceptionClause *clause = ctx.header->clauses + i;
		VERIFIER_DEBUG (printf ("clause try %x len %x filter at %x handler at %x len %x\n", clause->try_offset, clause->try_len, clause->data.filter_offset, clause->handler_offset, clause->handler_len); );

		if (clause->try_offset > ctx.code_size || ADD_IS_GREATER_OR_OVF (clause->try_offset, clause->try_len, ctx.code_size))
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("try clause out of bounds at 0x%04x", clause->try_offset));

		if (clause->try_len <= 0)
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("try clause len <= 0 at 0x%04x", clause->try_offset));

		if (clause->handler_offset > ctx.code_size || ADD_IS_GREATER_OR_OVF (clause->handler_offset, clause->handler_len, ctx.code_size))
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("handler clause out of bounds at 0x%04x", clause->try_offset));

		if (clause->handler_len <= 0)
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("handler clause len <= 0 at 0x%04x", clause->try_offset));

		if (clause->try_offset < clause->handler_offset && ADD_IS_GREATER_OR_OVF (clause->try_offset, clause->try_len, HANDLER_START (clause)))
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("try block (at 0x%04x) includes handler block (at 0x%04x)", clause->try_offset, clause->handler_offset));

		if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
			if (clause->data.filter_offset > ctx.code_size)
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("filter clause out of bounds at 0x%04x", clause->try_offset));

			if (clause->data.filter_offset >= clause->handler_offset)
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("filter clause must come before the handler clause at 0x%04x", clause->data.filter_offset));
		}

		for (n = i + 1; n < ctx.header->num_clauses && ctx.valid; ++n)
			verify_clause_relationship (&ctx, clause, ctx.header->clauses + n);

		if (!ctx.valid)
			break;

		ctx.code [clause->try_offset].flags |= IL_CODE_FLAG_WAS_TARGET;
		if (clause->try_offset + clause->try_len < ctx.code_size)
			ctx.code [clause->try_offset + clause->try_len].flags |= IL_CODE_FLAG_WAS_TARGET;
		if (clause->handler_offset + clause->handler_len < ctx.code_size)
			ctx.code [clause->handler_offset + clause->handler_len].flags |= IL_CODE_FLAG_WAS_TARGET;

		if (clause->flags == MONO_EXCEPTION_CLAUSE_NONE) {
			if (!clause->data.catch_class) {
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Catch clause %d with invalid type", i));
				break;
			}
		
			init_stack_with_value_at_exception_boundary (&ctx, ctx.code + clause->handler_offset, clause->data.catch_class);
		}
		else if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
			init_stack_with_value_at_exception_boundary (&ctx, ctx.code + clause->data.filter_offset, mono_defaults.exception_class);
			init_stack_with_value_at_exception_boundary (&ctx, ctx.code + clause->handler_offset, mono_defaults.exception_class);	
		}
	}

	original_bb = bb = mono_basic_block_split (method, &error);
	if (!mono_error_ok (&error)) {
		ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid branch target: %s", mono_error_get_message (&error)));
		mono_error_cleanup (&error);
		goto cleanup;
	}
	g_assert (bb);

	while (ip < end && ctx.valid) {
		ip_offset = ip - code_start;
		{
			const unsigned char *ip_copy = ip;
			int size, op;

			if (ip_offset > bb->end) {
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Branch or EH block at [0x%04x] targets middle instruction at 0x%04x", bb->end, ip_offset));
				goto cleanup;
			}

			if (ip_offset == bb->end)
				bb = bb->next;
	
			size = mono_opcode_value_and_size (&ip_copy, end, &op);
			if (size == -1) {
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid instruction %x at 0x%04x", *ip, ip_offset));
				goto cleanup;
			}

			if (ADD_IS_GREATER_OR_OVF (ip_offset, size, bb->end)) {
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Branch or EH block targets middle of instruction at 0x%04x", ip_offset));
				goto cleanup;
			}

			/*Last Instruction*/
			if (ip_offset + size == bb->end && mono_opcode_is_prefix (op)) {
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Branch or EH block targets between prefix '%s' and instruction at 0x%04x", mono_opcode_name (op), ip_offset));
				goto cleanup;
			}

			if (bb->dead) {
				/*FIXME remove this once we move all bad branch checking code to use BB only*/
				ctx.code [ip_offset].flags |= IL_CODE_FLAG_SEEN;
				ip += size;
				continue;
			}
		}

		ctx.ip_offset = ip_offset = ip - code_start;

		/*We need to check against fallthrou in and out of protected blocks.
		 * For fallout we check the once a protected block ends, if the start flag is not set.
		 * Likewise for fallthru in, we check if ip is the start of a protected block and start is not set
		 * TODO convert these checks to be done using flags and not this loop
		 */
		for (i = 0; i < ctx.header->num_clauses && ctx.valid; ++i) {
			MonoExceptionClause *clause = ctx.header->clauses + i;

			if ((clause->try_offset + clause->try_len == ip_offset) && start == 0) {
				CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("fallthru off try block at 0x%04x", ip_offset));
				start = 1;
			}

			if ((clause->handler_offset + clause->handler_len == ip_offset) && start == 0) {
				if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
					ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("fallout of handler block at 0x%04x", ip_offset));
				else
					CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("fallout of handler block at 0x%04x", ip_offset));
				start = 1;
			}

			if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER && clause->handler_offset == ip_offset && start == 0) {
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("fallout of filter block at 0x%04x", ip_offset));
				start = 1;
			}

			if (clause->handler_offset == ip_offset && start == 0) {
				CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("fallthru handler block at 0x%04x", ip_offset));
				start = 1;
			}

			if (clause->try_offset == ip_offset && ctx.eval.size > 0 && start == 0) {
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Try to enter try block with a non-empty stack at 0x%04x", ip_offset));
				start = 1;
			}
		}

		if (!ctx.valid)
			break;

		if (need_merge) {
			VERIFIER_DEBUG ( printf ("extra merge needed! 0x%04x \n", ctx.target); );
			merge_stacks (&ctx, &ctx.eval, &ctx.code [ctx.target], FALSE, TRUE);
			need_merge = 0;	
		}
		merge_stacks (&ctx, &ctx.eval, &ctx.code[ip_offset], start, FALSE);
		start = 0;

		/*TODO we can fast detect a forward branch or exception block targeting code after prefix, we should fail fast*/
#ifdef MONO_VERIFIER_DEBUG
		{
			char *discode;
			discode = mono_disasm_code_one (NULL, method, ip, NULL);
			discode [strlen (discode) - 1] = 0; /* no \n */
			g_print ("[%d] %-29s (%d)\n",  ip_offset, discode, ctx.eval.size);
			g_free (discode);
		}
		dump_stack_state (&ctx.code [ip_offset]);
		dump_stack_state (&ctx.eval);
#endif

		switch (*ip) {
		case CEE_NOP:
		case CEE_BREAK:
			++ip;
			break;

		case CEE_LDARG_0:
		case CEE_LDARG_1:
		case CEE_LDARG_2:
		case CEE_LDARG_3:
			push_arg (&ctx, *ip - CEE_LDARG_0, FALSE);
			++ip;
			break;

		case CEE_LDARG_S:
		case CEE_LDARGA_S:
			code_bounds_check (2);
			push_arg (&ctx, ip [1],  *ip == CEE_LDARGA_S);
			ip += 2;
			break;

		case CEE_ADD_OVF_UN:
			do_binop (&ctx, *ip, add_ovf_un_table);
			++ip;
			break;

		case CEE_SUB_OVF_UN:
			do_binop (&ctx, *ip, sub_ovf_un_table);
			++ip;
			break;

		case CEE_ADD_OVF:
		case CEE_SUB_OVF:
		case CEE_MUL_OVF:
		case CEE_MUL_OVF_UN:
			do_binop (&ctx, *ip, bin_ovf_table);
			++ip;
			break;

		case CEE_ADD:
			do_binop (&ctx, *ip, add_table);
			++ip;
			break;

		case CEE_SUB:
			do_binop (&ctx, *ip, sub_table);
			++ip;
			break;

		case CEE_MUL:
		case CEE_DIV:
		case CEE_REM:
			do_binop (&ctx, *ip, bin_op_table);
			++ip;
			break;

		case CEE_AND:
		case CEE_DIV_UN:
		case CEE_OR:
		case CEE_REM_UN:
		case CEE_XOR:
			do_binop (&ctx, *ip, int_bin_op_table);
			++ip;
			break;

		case CEE_SHL:
		case CEE_SHR:
		case CEE_SHR_UN:
			do_binop (&ctx, *ip, shift_op_table);
			++ip;
			break;

		case CEE_POP:
			if (!check_underflow (&ctx, 1))
				break;
			stack_pop_safe (&ctx);
			++ip;
			break;

		case CEE_RET:
			do_ret (&ctx);
			++ip;
			start = 1;
			break;

		case CEE_LDLOC_0:
		case CEE_LDLOC_1:
		case CEE_LDLOC_2:
		case CEE_LDLOC_3:
			/*TODO support definite assignment verification? */
			push_local (&ctx, *ip - CEE_LDLOC_0, FALSE);
			++ip;
			break;

		case CEE_STLOC_0:
		case CEE_STLOC_1:
		case CEE_STLOC_2:
		case CEE_STLOC_3:
			store_local (&ctx, *ip - CEE_STLOC_0);
			++ip;
			break;

		case CEE_STLOC_S:
			code_bounds_check (2);
			store_local (&ctx, ip [1]);
			ip += 2;
			break;

		case CEE_STARG_S:
			code_bounds_check (2);
			store_arg (&ctx, ip [1]);
			ip += 2;
			break;

		case CEE_LDC_I4_M1:
		case CEE_LDC_I4_0:
		case CEE_LDC_I4_1:
		case CEE_LDC_I4_2:
		case CEE_LDC_I4_3:
		case CEE_LDC_I4_4:
		case CEE_LDC_I4_5:
		case CEE_LDC_I4_6:
		case CEE_LDC_I4_7:
		case CEE_LDC_I4_8:
			if (check_overflow (&ctx))
				stack_push_val (&ctx, TYPE_I4, &mono_defaults.int32_class->byval_arg);
			++ip;
			break;

		case CEE_LDC_I4_S:
			code_bounds_check (2);
			if (check_overflow (&ctx))
				stack_push_val (&ctx, TYPE_I4, &mono_defaults.int32_class->byval_arg);
			ip += 2;
			break;

		case CEE_LDC_I4:
			code_bounds_check (5);
			if (check_overflow (&ctx))
				stack_push_val (&ctx,TYPE_I4, &mono_defaults.int32_class->byval_arg);
			ip += 5;
			break;

		case CEE_LDC_I8:
			code_bounds_check (9);
			if (check_overflow (&ctx))
				stack_push_val (&ctx,TYPE_I8, &mono_defaults.int64_class->byval_arg);
			ip += 9;
			break;

		case CEE_LDC_R4:
			code_bounds_check (5);
			if (check_overflow (&ctx))
				stack_push_val (&ctx, TYPE_R8, &mono_defaults.double_class->byval_arg);
			ip += 5;
			break;

		case CEE_LDC_R8:
			code_bounds_check (9);
			if (check_overflow (&ctx))
				stack_push_val (&ctx, TYPE_R8, &mono_defaults.double_class->byval_arg);
			ip += 9;
			break;

		case CEE_LDNULL:
			if (check_overflow (&ctx))
				stack_push_val (&ctx, TYPE_COMPLEX | NULL_LITERAL_MASK, &mono_defaults.object_class->byval_arg);
			++ip;
			break;

		case CEE_BEQ_S:
		case CEE_BNE_UN_S:
			code_bounds_check (2);
			do_branch_op (&ctx, (signed char)ip [1] + 2, cmp_br_eq_op);
			ip += 2;
			need_merge = 1;
			break;

		case CEE_BGE_S:
		case CEE_BGT_S:
		case CEE_BLE_S:
		case CEE_BLT_S:
		case CEE_BGE_UN_S:
		case CEE_BGT_UN_S:
		case CEE_BLE_UN_S:
		case CEE_BLT_UN_S:
			code_bounds_check (2);
			do_branch_op (&ctx, (signed char)ip [1] + 2, cmp_br_op);
			ip += 2;
			need_merge = 1;
			break;

		case CEE_BEQ:
		case CEE_BNE_UN:
			code_bounds_check (5);
			do_branch_op (&ctx, (gint32)read32 (ip + 1) + 5, cmp_br_eq_op);
			ip += 5;
			need_merge = 1;
			break;

		case CEE_BGE:
		case CEE_BGT:
		case CEE_BLE:
		case CEE_BLT:
		case CEE_BGE_UN:
		case CEE_BGT_UN:
		case CEE_BLE_UN:
		case CEE_BLT_UN:
			code_bounds_check (5);
			do_branch_op (&ctx, (gint32)read32 (ip + 1) + 5, cmp_br_op);
			ip += 5;
			need_merge = 1;
			break;

		case CEE_LDLOC_S:
		case CEE_LDLOCA_S:
			code_bounds_check (2);
			push_local (&ctx, ip[1], *ip == CEE_LDLOCA_S);
			ip += 2;
			break;

		case CEE_UNUSED99:
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Use of the `unused' opcode"));
			++ip;
			break; 

		case CEE_DUP: {
			ILStackDesc *top;
			if (!check_underflow (&ctx, 1))
				break;
			if (!check_overflow (&ctx))
				break;
			top = stack_push (&ctx);
			copy_stack_value (top, stack_peek (&ctx, 1));
			++ip;
			break;
		}

		case CEE_JMP:
			code_bounds_check (5);
			if (ctx.eval.size)
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Eval stack must be empty in jmp at 0x%04x", ip_offset));
			token = read32 (ip + 1);
			if (in_any_block (ctx.header, ip_offset))
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("jmp cannot escape exception blocks at 0x%04x", ip_offset));

			CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Intruction jmp is not verifiable at 0x%04x", ctx.ip_offset));
			/*
			 * FIXME: check signature, retval, arguments etc.
			 */
			ip += 5;
			break;
		case CEE_CALL:
		case CEE_CALLVIRT:
			code_bounds_check (5);
			do_invoke_method (&ctx, read32 (ip + 1), *ip == CEE_CALLVIRT);
			ip += 5;
			break;

		case CEE_CALLI:
			code_bounds_check (5);
			token = read32 (ip + 1);
			/*
			 * FIXME: check signature, retval, arguments etc.
			 * FIXME: check requirements for tail call
			 */
			CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Intruction calli is not verifiable at 0x%04x", ctx.ip_offset));
			ip += 5;
			break;
		case CEE_BR_S:
			code_bounds_check (2);
			do_static_branch (&ctx, (signed char)ip [1] + 2);
			need_merge = 1;
			ip += 2;
			start = 1;
			break;

		case CEE_BRFALSE_S:
		case CEE_BRTRUE_S:
			code_bounds_check (2);
			do_boolean_branch_op (&ctx, (signed char)ip [1] + 2);
			ip += 2;
			need_merge = 1;
			break;

		case CEE_BR:
			code_bounds_check (5);
			do_static_branch (&ctx, (gint32)read32 (ip + 1) + 5);
			need_merge = 1;
			ip += 5;
			start = 1;
			break;

		case CEE_BRFALSE:
		case CEE_BRTRUE:
			code_bounds_check (5);
			do_boolean_branch_op (&ctx, (gint32)read32 (ip + 1) + 5);
			ip += 5;
			need_merge = 1;
			break;

		case CEE_SWITCH: {
			guint32 entries;
			code_bounds_check (5);
			entries = read32 (ip + 1);

			if (entries > 0xFFFFFFFFU / sizeof (guint32))
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Too many switch entries %x at 0x%04x", entries, ctx.ip_offset));

			ip += 5;
			code_bounds_check (sizeof (guint32) * entries);
			
			do_switch (&ctx, entries, ip);
			ip += sizeof (guint32) * entries;
			break;
		}
		case CEE_LDIND_I1:
		case CEE_LDIND_U1:
		case CEE_LDIND_I2:
		case CEE_LDIND_U2:
		case CEE_LDIND_I4:
		case CEE_LDIND_U4:
		case CEE_LDIND_I8:
		case CEE_LDIND_I:
		case CEE_LDIND_R4:
		case CEE_LDIND_R8:
		case CEE_LDIND_REF:
			do_load_indirect (&ctx, *ip);
			++ip;
			break;
			
		case CEE_STIND_REF:
		case CEE_STIND_I1:
		case CEE_STIND_I2:
		case CEE_STIND_I4:
		case CEE_STIND_I8:
		case CEE_STIND_R4:
		case CEE_STIND_R8:
		case CEE_STIND_I:
			do_store_indirect (&ctx, *ip);
			++ip;
			break;

		case CEE_NOT:
		case CEE_NEG:
			do_unary_math_op (&ctx, *ip);
			++ip;
			break;

		case CEE_CONV_I1:
		case CEE_CONV_I2:
		case CEE_CONV_I4:
		case CEE_CONV_U1:
		case CEE_CONV_U2:
		case CEE_CONV_U4:
			do_conversion (&ctx, TYPE_I4);
			++ip;
			break;			

		case CEE_CONV_I8:
		case CEE_CONV_U8:
			do_conversion (&ctx, TYPE_I8);
			++ip;
			break;			

		case CEE_CONV_R4:
		case CEE_CONV_R8:
		case CEE_CONV_R_UN:
			do_conversion (&ctx, TYPE_R8);
			++ip;
			break;			

		case CEE_CONV_I:
		case CEE_CONV_U:
			do_conversion (&ctx, TYPE_NATIVE_INT);
			++ip;
			break;

		case CEE_CPOBJ:
			code_bounds_check (5);
			do_cpobj (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_LDOBJ:
			code_bounds_check (5);
			do_ldobj_value (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_LDSTR:
			code_bounds_check (5);
			do_ldstr (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_NEWOBJ:
			code_bounds_check (5);
			do_newobj (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_CASTCLASS:
		case CEE_ISINST:
			code_bounds_check (5);
			do_cast (&ctx, read32 (ip + 1), *ip == CEE_CASTCLASS ? "castclass" : "isinst");
			ip += 5;
			break;

		case CEE_UNUSED58:
		case CEE_UNUSED1:
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Use of the `unused' opcode"));
			++ip;
			break;

		case CEE_UNBOX:
			code_bounds_check (5);
			do_unbox_value (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_THROW:
			do_throw (&ctx);
			start = 1;
			++ip;
			break;

		case CEE_LDFLD:
		case CEE_LDFLDA:
			code_bounds_check (5);
			do_push_field (&ctx, read32 (ip + 1), *ip == CEE_LDFLDA);
			ip += 5;
			break;

		case CEE_LDSFLD:
		case CEE_LDSFLDA:
			code_bounds_check (5);
			do_push_static_field (&ctx, read32 (ip + 1), *ip == CEE_LDSFLDA);
			ip += 5;
			break;

		case CEE_STFLD:
			code_bounds_check (5);
			do_store_field (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_STSFLD:
			code_bounds_check (5);
			do_store_static_field (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_STOBJ:
			code_bounds_check (5);
			do_stobj (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_CONV_OVF_I1_UN:
		case CEE_CONV_OVF_I2_UN:
		case CEE_CONV_OVF_I4_UN:
		case CEE_CONV_OVF_U1_UN:
		case CEE_CONV_OVF_U2_UN:
		case CEE_CONV_OVF_U4_UN:
			do_conversion (&ctx, TYPE_I4);
			++ip;
			break;			

		case CEE_CONV_OVF_I8_UN:
		case CEE_CONV_OVF_U8_UN:
			do_conversion (&ctx, TYPE_I8);
			++ip;
			break;			

		case CEE_CONV_OVF_I_UN:
		case CEE_CONV_OVF_U_UN:
			do_conversion (&ctx, TYPE_NATIVE_INT);
			++ip;
			break;

		case CEE_BOX:
			code_bounds_check (5);
			do_box_value (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_NEWARR:
			code_bounds_check (5);
			do_newarr (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_LDLEN:
			do_ldlen (&ctx);
			++ip;
			break;

		case CEE_LDELEMA:
			code_bounds_check (5);
			do_ldelema (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_LDELEM_I1:
		case CEE_LDELEM_U1:
		case CEE_LDELEM_I2:
		case CEE_LDELEM_U2:
		case CEE_LDELEM_I4:
		case CEE_LDELEM_U4:
		case CEE_LDELEM_I8:
		case CEE_LDELEM_I:
		case CEE_LDELEM_R4:
		case CEE_LDELEM_R8:
		case CEE_LDELEM_REF:
			do_ldelem (&ctx, *ip, 0);
			++ip;
			break;

		case CEE_STELEM_I:
		case CEE_STELEM_I1:
		case CEE_STELEM_I2:
		case CEE_STELEM_I4:
		case CEE_STELEM_I8:
		case CEE_STELEM_R4:
		case CEE_STELEM_R8:
		case CEE_STELEM_REF:
			do_stelem (&ctx, *ip, 0);
			++ip;
			break;

		case CEE_LDELEM:
			code_bounds_check (5);
			do_ldelem (&ctx, *ip, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_STELEM:
			code_bounds_check (5);
			do_stelem (&ctx, *ip, read32 (ip + 1));
			ip += 5;
			break;
			
		case CEE_UNBOX_ANY:
			code_bounds_check (5);
			do_unbox_any (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_CONV_OVF_I1:
		case CEE_CONV_OVF_U1:
		case CEE_CONV_OVF_I2:
		case CEE_CONV_OVF_U2:
		case CEE_CONV_OVF_I4:
		case CEE_CONV_OVF_U4:
			do_conversion (&ctx, TYPE_I4);
			++ip;
			break;

		case CEE_CONV_OVF_I8:
		case CEE_CONV_OVF_U8:
			do_conversion (&ctx, TYPE_I8);
			++ip;
			break;

		case CEE_CONV_OVF_I:
		case CEE_CONV_OVF_U:
			do_conversion (&ctx, TYPE_NATIVE_INT);
			++ip;
			break;

		case CEE_REFANYVAL:
			code_bounds_check (5);
			do_refanyval (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_CKFINITE:
			do_ckfinite (&ctx);
			++ip;
			break;

		case CEE_MKREFANY:
			code_bounds_check (5);
			do_mkrefany (&ctx,  read32 (ip + 1));
			ip += 5;
			break;

		case CEE_LDTOKEN:
			code_bounds_check (5);
			do_load_token (&ctx, read32 (ip + 1));
			ip += 5;
			break;

		case CEE_ENDFINALLY:
			if (!is_correct_endfinally (ctx.header, ip_offset))
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("endfinally must be used inside a finally/fault handler at 0x%04x", ctx.ip_offset));
			ctx.eval.size = 0;
			start = 1;
			++ip;
			break;

		case CEE_LEAVE:
			code_bounds_check (5);
			do_leave (&ctx, read32 (ip + 1) + 5);
			ip += 5;
			start = 1;
			break;

		case CEE_LEAVE_S:
			code_bounds_check (2);
			do_leave (&ctx, (signed char)ip [1] + 2);
			ip += 2;
			start = 1;
			break;

		case CEE_PREFIX1:
			code_bounds_check (2);
			++ip;
			switch (*ip) {
			case CEE_STLOC:
				code_bounds_check (3);
				store_local (&ctx, read16 (ip + 1));
				ip += 3;
				break;

			case CEE_CEQ:
				do_cmp_op (&ctx, cmp_br_eq_op, *ip);
				++ip;
				break;

			case CEE_CGT:
			case CEE_CGT_UN:
			case CEE_CLT:
			case CEE_CLT_UN:
				do_cmp_op (&ctx, cmp_br_op, *ip);
				++ip;
				break;

			case CEE_STARG:
				code_bounds_check (3);
				store_arg (&ctx, read16 (ip + 1) );
				ip += 3;
				break;


			case CEE_ARGLIST:
				if (!check_overflow (&ctx))
					break;
				if (ctx.signature->call_convention != MONO_CALL_VARARG)
					ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Cannot use arglist on method without VARGARG calling convention at 0x%04x", ctx.ip_offset));
				set_stack_value (&ctx, stack_push (&ctx), &mono_defaults.argumenthandle_class->byval_arg, FALSE);
				++ip;
				break;
	
			case CEE_LDFTN:
				code_bounds_check (5);
				do_load_function_ptr (&ctx, read32 (ip + 1), FALSE);
				ip += 5;
				break;

			case CEE_LDVIRTFTN:
				code_bounds_check (5);
				do_load_function_ptr (&ctx, read32 (ip + 1), TRUE);
				ip += 5;
				break;

			case CEE_LDARG:
			case CEE_LDARGA:
				code_bounds_check (3);
				push_arg (&ctx, read16 (ip + 1),  *ip == CEE_LDARGA);
				ip += 3;
				break;

			case CEE_LDLOC:
			case CEE_LDLOCA:
				code_bounds_check (3);
				push_local (&ctx, read16 (ip + 1), *ip == CEE_LDLOCA);
				ip += 3;
				break;

			case CEE_LOCALLOC:
				do_localloc (&ctx);
				++ip;
				break;

			case CEE_UNUSED56:
			case CEE_UNUSED57:
			case CEE_UNUSED70:
			case CEE_UNUSED:
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Use of the `unused' opcode"));
				++ip;
				break;
			case CEE_ENDFILTER:
				do_endfilter (&ctx);
				start = 1;
				++ip;
				break;
			case CEE_UNALIGNED_:
				code_bounds_check (2);
				prefix |= PREFIX_UNALIGNED;
				ip += 2;
				break;
			case CEE_VOLATILE_:
				prefix |= PREFIX_VOLATILE;
				++ip;
				break;
			case CEE_TAIL_:
				prefix |= PREFIX_TAIL;
				++ip;
				if (ip < end && (*ip != CEE_CALL && *ip != CEE_CALLI && *ip != CEE_CALLVIRT))
					ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("tail prefix must be used only with call opcodes at 0x%04x", ip_offset));
				break;

			case CEE_INITOBJ:
				code_bounds_check (5);
				do_initobj (&ctx, read32 (ip + 1));
				ip += 5;
				break;

			case CEE_CONSTRAINED_:
				code_bounds_check (5);
				ctx.constrained_type = get_boxable_mono_type (&ctx, read32 (ip + 1), "constrained.");
				prefix |= PREFIX_CONSTRAINED;
				ip += 5;
				break;
	
			case CEE_READONLY_:
				prefix |= PREFIX_READONLY;
				ip++;
				break;

			case CEE_CPBLK:
				CLEAR_PREFIX (&ctx, PREFIX_UNALIGNED | PREFIX_VOLATILE);
				if (!check_underflow (&ctx, 3))
					break;
				CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Instruction cpblk is not verifiable at 0x%04x", ctx.ip_offset));
				ip++;
				break;
				
			case CEE_INITBLK:
				CLEAR_PREFIX (&ctx, PREFIX_UNALIGNED | PREFIX_VOLATILE);
				if (!check_underflow (&ctx, 3))
					break;
				CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Instruction initblk is not verifiable at 0x%04x", ctx.ip_offset));
				ip++;
				break;
				
			case CEE_NO_:
				ip += 2;
				break;
			case CEE_RETHROW:
				if (!is_correct_rethrow (ctx.header, ip_offset))
					ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("rethrow must be used inside a catch handler at 0x%04x", ctx.ip_offset));
				ctx.eval.size = 0;
				start = 1;
				++ip;
				break;

			case CEE_SIZEOF:
				code_bounds_check (5);
				do_sizeof (&ctx, read32 (ip + 1));
				ip += 5;
				break;

			case CEE_REFANYTYPE:
				do_refanytype (&ctx);
				++ip;
				break;

			default:
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid instruction FE %x at 0x%04x", *ip, ctx.ip_offset));
				++ip;
			}
			break;

		default:
			ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid instruction %x at 0x%04x", *ip, ctx.ip_offset));
			++ip;
		}

		/*TODO we can fast detect a forward branch or exception block targeting code after prefix, we should fail fast*/
		if (prefix) {
			if (!ctx.prefix_set) //first prefix
				ctx.code [ctx.ip_offset].flags |= IL_CODE_FLAG_SEEN;
			ctx.prefix_set |= prefix;
			ctx.has_flags = TRUE;
			prefix = 0;
		} else {
			if (!ctx.has_flags)
				ctx.code [ctx.ip_offset].flags |= IL_CODE_FLAG_SEEN;

			if (ctx.prefix_set & PREFIX_CONSTRAINED)
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid instruction after constrained prefix at 0x%04x", ctx.ip_offset));
			if (ctx.prefix_set & PREFIX_READONLY)
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid instruction after readonly prefix at 0x%04x", ctx.ip_offset));
			if (ctx.prefix_set & PREFIX_VOLATILE)
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid instruction after volatile prefix at 0x%04x", ctx.ip_offset));
			if (ctx.prefix_set & PREFIX_UNALIGNED)
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid instruction after unaligned prefix at 0x%04x", ctx.ip_offset));
			ctx.prefix_set = prefix = 0;
			ctx.has_flags = FALSE;
		}
	}
	/*
	 * if ip != end we overflowed: mark as error.
	 */
	if ((ip != end || !start) && ctx.verifiable && !ctx.list) {
		ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Run ahead of method code at 0x%04x", ip_offset));
	}

	/*We should guard against the last decoded opcode, otherwise we might add errors that doesn't make sense.*/
	for (i = 0; i < ctx.code_size && i < ip_offset; ++i) {
		if (ctx.code [i].flags & IL_CODE_FLAG_WAS_TARGET) {
			if (!(ctx.code [i].flags & IL_CODE_FLAG_SEEN))
				ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Branch or exception block target middle of intruction at 0x%04x", i));

			if (ctx.code [i].flags & IL_CODE_DELEGATE_SEQUENCE)
				CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Branch to delegate code sequence at 0x%04x", i));
		}
		if ((ctx.code [i].flags & IL_CODE_LDFTN_DELEGATE_NONFINAL_VIRTUAL) && ctx.has_this_store)
			CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Invalid ldftn with virtual function in method with stdarg 0 at  0x%04x", i));

		if ((ctx.code [i].flags & IL_CODE_CALL_NONFINAL_VIRTUAL) && ctx.has_this_store)
			CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Invalid call to a non-final virtual function in method with stdarg.0 or ldarga.0 at  0x%04x", i));
	}

	if (mono_method_is_constructor (ctx.method) && !ctx.super_ctor_called && !ctx.method->klass->valuetype && ctx.method->klass != mono_defaults.object_class) {
		char *method_name = mono_method_full_name (ctx.method, TRUE);
		char *type = mono_type_get_full_name (ctx.method->klass);
		if (ctx.method->klass->parent && ctx.method->klass->parent->exception_type != MONO_EXCEPTION_NONE)
			CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Constructor %s for type %s not calling base type ctor due to a TypeLoadException on base type.", method_name, type));
		else
			CODE_NOT_VERIFIABLE (&ctx, g_strdup_printf ("Constructor %s for type %s not calling base type ctor.", method_name, type));
		g_free (method_name);
		g_free (type);
	}

cleanup:
	if (ctx.code) {
		for (i = 0; i < ctx.header->code_size; ++i) {
			if (ctx.code [i].stack)
				g_free (ctx.code [i].stack);
		}
	}

	for (tmp = ctx.funptrs; tmp; tmp = tmp->next)
		g_free (tmp->data);
	g_slist_free (ctx.funptrs);

	for (tmp = ctx.exception_types; tmp; tmp = tmp->next)
		mono_metadata_free_type (tmp->data);
	g_slist_free (ctx.exception_types);

	for (i = 0; i < ctx.num_locals; ++i) {
		if (ctx.locals [i])
			mono_metadata_free_type (ctx.locals [i]);
	}
	for (i = 0; i < ctx.max_args; ++i) {
		if (ctx.params [i])
			mono_metadata_free_type (ctx.params [i]);
	}

	if (ctx.eval.stack)
		g_free (ctx.eval.stack);
	if (ctx.code)
		g_free (ctx.code);
	g_free (ctx.locals);
	g_free (ctx.params);
	mono_basic_block_free (original_bb);
	mono_metadata_free_mh (ctx.header);

	finish_collect_stats ();
	return ctx.list;

Project: mono
File: reflection.c

mono_reflection_get_custom_attrs (MonoObject *obj)
{
	return mono_reflection_get_custom_attrs_by_type (obj, NULL);
}

Project: mono
File: reflection.c

guint32
mono_declsec_flags_from_method (MonoMethod *method)
{
	if (method->flags & METHOD_ATTRIBUTE_HAS_SECURITY) {
		/* FIXME: No cache (for the moment) */
		guint32 idx = mono_method_get_index (method);
		idx <<= MONO_HAS_DECL_SECURITY_BITS;
		idx |= MONO_HAS_DECL_SECURITY_METHODDEF;
		return mono_declsec_get_flags (method->klass->image, idx);
	}
	return 0;

Project: mono
File: reflection.c

get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types)
{
	guint32 param_index, i, lastp, crow = 0;
	guint32 param_cols [MONO_PARAM_SIZE], const_cols [MONO_CONSTANT_SIZE];
	gint32 idx;

	MonoClass *klass = method->klass;
	MonoImage *image = klass->image;
	MonoMethodSignature *methodsig = mono_method_signature (method);

	MonoTableInfo *constt;
	MonoTableInfo *methodt;
	MonoTableInfo *paramt;

	if (!methodsig->param_count)
		return;

	mono_class_init (klass);

	if (klass->image->dynamic) {
		MonoReflectionMethodAux *aux;
		if (method->is_inflated)
			method = ((MonoMethodInflated*)method)->declaring;
		aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
		if (aux && aux->param_defaults) {
			memcpy (blobs, &(aux->param_defaults [1]), methodsig->param_count * sizeof (char*));
			memcpy (types, &(aux->param_default_types [1]), methodsig->param_count * sizeof (guint32));
		}
		return;
	}

	methodt = &klass->image->tables [MONO_TABLE_METHOD];
	paramt = &klass->image->tables [MONO_TABLE_PARAM];
	constt = &image->tables [MONO_TABLE_CONSTANT];

	idx = mono_method_get_index (method) - 1;
	g_assert (idx != -1);

	param_index = mono_metadata_decode_row_col (methodt, idx, MONO_METHOD_PARAMLIST);
	if (idx + 1 < methodt->rows)
		lastp = mono_metadata_decode_row_col (methodt, idx + 1, MONO_METHOD_PARAMLIST);
	else
		lastp = paramt->rows + 1;

	for (i = param_index; i < lastp; ++i) {
		guint32 paramseq;

		mono_metadata_decode_row (paramt, i - 1, param_cols, MONO_PARAM_SIZE);
		paramseq = param_cols [MONO_PARAM_SEQUENCE];

		if (!(param_cols [MONO_PARAM_FLAGS] & PARAM_ATTRIBUTE_HAS_DEFAULT))
			continue;

		crow = mono_metadata_get_constant_index (image, MONO_TOKEN_PARAM_DEF | i, crow + 1);
		if (!crow) {
			continue;
		}
	
		mono_metadata_decode_row (constt, crow - 1, const_cols, MONO_CONSTANT_SIZE);
		blobs [paramseq - 1] = (gpointer) mono_metadata_blob_heap (image, const_cols [MONO_CONSTANT_VALUE]);
		types [paramseq - 1] = const_cols [MONO_CONSTANT_TYPE];
	}

	return;
}

Project: mono
File: verify.c

do_leave (VerifyContext *ctx, int delta)
{
	int target = ((gint32)ctx->ip_offset) + delta;
	if (target >= ctx->code_size || target < 0)
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Branch target out of code at 0x%04x", ctx->ip_offset));

	if (!is_correct_leave (ctx->header, ctx->ip_offset, target))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Leave not allowed in finally block at 0x%04x", ctx->ip_offset));
	ctx->eval.size = 0;
}

Project: mono
File: reflection.c

mono_get_dbnull_object (MonoDomain *domain)
{
	MonoObject *obj;
	static MonoClassField *dbnull_value_field = NULL;
	
	if (!dbnull_value_field) {
		MonoClass *dbnull_klass;
		dbnull_klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
		mono_class_init (dbnull_klass);
		dbnull_value_field = mono_class_get_field_from_name (dbnull_klass, "Value");
		g_assert (dbnull_value_field);
	}
	obj = mono_field_get_value_object (domain, dbnull_value_field, NULL); 
	g_assert (obj);
	return obj;
}

Project: mono
File: verify.c

gboolean
mono_verifier_is_enabled_for_method (MonoMethod *method)
{
	/* The verifier was disabled at compile time */
	return FALSE;

Project: mono
File: reflection.c

fixup_resource_directory (char *res_section, char *p, guint32 rva)
{
	MonoPEResourceDir *dir = (MonoPEResourceDir*)p;
	int i;

	p += sizeof (MonoPEResourceDir);
	for (i = 0; i < GUINT16_FROM_LE (dir->res_named_entries) + GUINT16_FROM_LE (dir->res_id_entries); ++i) {
		MonoPEResourceDirEntry *dir_entry = (MonoPEResourceDirEntry*)p;
		char *child = res_section + MONO_PE_RES_DIR_ENTRY_DIR_OFFSET (*dir_entry);
		if (MONO_PE_RES_DIR_ENTRY_IS_DIR (*dir_entry)) {
			fixup_resource_directory (res_section, child, rva);
		} else {
			MonoPEResourceDataEntry *data_entry = (MonoPEResourceDataEntry*)child;
			data_entry->rde_data_offset = GUINT32_TO_LE (GUINT32_FROM_LE (data_entry->rde_data_offset) + rva);
		}

		p += sizeof (MonoPEResourceDirEntry);
	}
}

Project: mono
File: reflection.c

static MonoBoolean
get_declsec_action (MonoImage *image, guint32 token, guint32 action, MonoDeclSecurityEntry *entry)
{
	guint32 cols [MONO_DECL_SECURITY_SIZE];
	MonoTableInfo *t;
	int i;

	int index = mono_metadata_declsec_from_index (image, token);
	if (index == -1)
		return FALSE;

	t =  &image->tables [MONO_TABLE_DECLSECURITY];
	for (i = index; i < t->rows; i++) {
		mono_metadata_decode_row (t, i, cols, MONO_DECL_SECURITY_SIZE);

		/* shortcut - index are ordered */
		if (token != cols [MONO_DECL_SECURITY_PARENT])
			return FALSE;

		if (cols [MONO_DECL_SECURITY_ACTION] == action) {
			const char *metadata = mono_metadata_blob_heap (image, cols [MONO_DECL_SECURITY_PERMISSIONSET]);
			entry->blob = (char*) (metadata + 2);
			entry->size = mono_metadata_decode_blob_size (metadata, &metadata);
			return TRUE;
		}
	}

	return FALSE;

Project: mono
File: verify.c

stack_slot_stack_type_full_name (ILStackDesc *value)
{
	GString *str = g_string_new ("");
	char *result;
	gboolean has_pred = FALSE, first = TRUE;

	if ((value->stype & TYPE_MASK) != value->stype) {
		g_string_append(str, "[");
		APPEND_WITH_PREDICATE (stack_slot_is_this_pointer, "this");
		APPEND_WITH_PREDICATE (stack_slot_is_boxed_value, "boxed");
		APPEND_WITH_PREDICATE (stack_slot_is_null_literal, "null");
		APPEND_WITH_PREDICATE (stack_slot_is_managed_mutability_pointer, "cmmp");
		APPEND_WITH_PREDICATE (stack_slot_is_managed_pointer, "mp");
		has_pred = TRUE;
	}

	if (mono_type_is_generic_argument (value->type) && !stack_slot_is_boxed_value (value)) {
		if (!has_pred)
			g_string_append(str, "[");
		if (!first)
			g_string_append (str, ", ");
		g_string_append (str, "unboxed");
		has_pred = TRUE;
	}

	if (has_pred)
		g_string_append(str, "] ");

	g_string_append (str, stack_slot_get_name (value));
	result = str->str;
	g_string_free (str, FALSE);
	return result;
}

Project: mono
File: reflection.c

mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
{
	MonoArray *result;
	MonoObject *attr;
	int i;
	
	result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs);
	for (i = 0; i < cinfo->num_attrs; ++i) {
		attr = create_custom_attr_data (cinfo->image, &cinfo->attrs [i]);
		mono_array_setref (result, i, attr);
	}
	return result;
}

Project: mono
File: reflection.c

void
mono_reflection_create_generic_class (MonoReflectionTypeBuilder *tb)
{
	g_assert_not_reached ();

Project: mono
File: reflection.c

static MonoMethod*
reflection_methodbuilder_to_mono_method (MonoClass *klass,
					 ReflectionMethodBuilder *rmb,
					 MonoMethodSignature *sig)
{
	MonoError error;
	MonoMethod *m;
	MonoMethodWrapper *wrapperm;
	MonoMarshalSpec **specs;
	MonoReflectionMethodAux *method_aux;
	MonoImage *image;
	gboolean dynamic;
	int i;

	mono_error_init (&error);
	/*
	 * Methods created using a MethodBuilder should have their memory allocated
	 * inside the image mempool, while dynamic methods should have their memory
	 * malloc'd.
	 */
	dynamic = rmb->refs != NULL;
	image = dynamic ? NULL : klass->image;

	if (!dynamic)
		g_assert (!klass->generic_class);

	mono_loader_lock ();

	if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
			(rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
		m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
	else
		m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);

	wrapperm = (MonoMethodWrapper*)m;

	m->dynamic = dynamic;
	m->slot = -1;
	m->flags = rmb->attrs;
	m->iflags = rmb->iattrs;
	m->name = mono_string_to_utf8_image (image, rmb->name, &error);
	g_assert (mono_error_ok (&error));
	m->klass = klass;
	m->signature = sig;
	m->sre_method = TRUE;
	m->skip_visibility = rmb->skip_visibility;
	if (rmb->table_idx)
		m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);

	if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
		if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
			m->string_ctor = 1;

		m->signature->pinvoke = 1;
	} else if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
		m->signature->pinvoke = 1;

		method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);

		method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_image (image, rmb->dllentry, &error) : image_strdup (image, m->name);
		g_assert (mono_error_ok (&error));
		method_aux->dll = mono_string_to_utf8_image (image, rmb->dll, &error);
		g_assert (mono_error_ok (&error));
		
		((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;

		if (klass->image->dynamic)
			g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);

		mono_loader_unlock ();

		return m;
	} else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
			   !(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
		MonoMethodHeader *header;
		guint32 code_size;
		gint32 max_stack, i;
		gint32 num_locals = 0;
		gint32 num_clauses = 0;
		guint8 *code;

		if (rmb->ilgen) {
			code = mono_array_addr (rmb->ilgen->code, guint8, 0);
			code_size = rmb->ilgen->code_len;
			max_stack = rmb->ilgen->max_stack;
			num_locals = rmb->ilgen->locals ? mono_array_length (rmb->ilgen->locals) : 0;
			if (rmb->ilgen->ex_handlers)
				num_clauses = method_count_clauses (rmb->ilgen);
		} else {
			if (rmb->code) {
				code = mono_array_addr (rmb->code, guint8, 0);
				code_size = mono_array_length (rmb->code);
				/* we probably need to run a verifier on the code... */
				max_stack = 8; 
			}
			else {
				code = NULL;
				code_size = 0;
				max_stack = 8;
			}
		}

		header = image_g_malloc0 (image, MONO_SIZEOF_METHOD_HEADER + num_locals * sizeof (MonoType*));
		header->code_size = code_size;
		header->code = image_g_malloc (image, code_size);
		memcpy ((char*)header->code, code, code_size);
		header->max_stack = max_stack;
		header->init_locals = rmb->init_locals;
		header->num_locals = num_locals;

		for (i = 0; i < num_locals; ++i) {
			MonoReflectionLocalBuilder *lb = 
				mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);

			header->locals [i] = image_g_new0 (image, MonoType, 1);
			memcpy (header->locals [i], mono_reflection_type_get_handle ((MonoReflectionType*)lb->type), MONO_SIZEOF_TYPE);
		}

		header->num_clauses = num_clauses;
		if (num_clauses) {
			header->clauses = method_encode_clauses (image, (MonoDynamicImage*)klass->image,
				 rmb->ilgen, num_clauses);
		}

		wrapperm->header = header;
	}

	if (rmb->generic_params) {
		int count = mono_array_length (rmb->generic_params);
		MonoGenericContainer *container = rmb->generic_container;

		g_assert (container);

		container->type_argc = count;
		container->type_params = image_g_new0 (image, MonoGenericParamFull, count);
		container->owner.method = m;

		m->is_generic = TRUE;
		mono_method_set_generic_container (m, container);

		for (i = 0; i < count; i++) {
			MonoReflectionGenericParam *gp =
				mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
			MonoGenericParamFull *param = (MonoGenericParamFull *) mono_reflection_type_get_handle ((MonoReflectionType*)gp)->data.generic_param;
			container->type_params [i] = *param;
		}

		/*
		 * The method signature might have pointers to generic parameters that belong to other methods.
		 * This is a valid SRE case, but the resulting method signature must be encoded using the proper
		 * generic parameters.
		 */
		for (i = 0; i < m->signature->param_count; ++i) {
			MonoType *t = m->signature->params [i];
			if (t->type == MONO_TYPE_MVAR) {
				MonoGenericParam *gparam =  t->data.generic_param;
				if (gparam->num < count) {
					m->signature->params [i] = mono_metadata_type_dup (image, m->signature->params [i]);
					m->signature->params [i]->data.generic_param = mono_generic_container_get_param (container, gparam->num);
				}

			}
		}

		if (klass->generic_container) {
			container->parent = klass->generic_container;
			container->context.class_inst = klass->generic_container->context.class_inst;
		}
		container->context.method_inst = mono_get_shared_generic_inst (container);
	}

	if (rmb->refs) {
		MonoMethodWrapper *mw = (MonoMethodWrapper*)m;
		int i;
		void **data;

		m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;

		mw->method_data = data = image_g_new (image, gpointer, rmb->nrefs + 1);
		data [0] = GUINT_TO_POINTER (rmb->nrefs);
		for (i = 0; i < rmb->nrefs; ++i)
			data [i + 1] = rmb->refs [i];
	}

	method_aux = NULL;

	/* Parameter info */
	if (rmb->pinfo) {
		if (!method_aux)
			method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
		method_aux->param_names = image_g_new0 (image, char *, mono_method_signature (m)->param_count + 1);
		for (i = 0; i <= m->signature->param_count; ++i) {
			MonoReflectionParamBuilder *pb;
			if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
				if ((i > 0) && (pb->attrs)) {
					/* Make a copy since it might point to a shared type structure */
					m->signature->params [i - 1] = mono_metadata_type_dup (klass->image, m->signature->params [i - 1]);
					m->signature->params [i - 1]->attrs = pb->attrs;
				}

				if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
					MonoDynamicImage *assembly;
					guint32 idx, def_type, len;
					char *p;
					const char *p2;

					if (!method_aux->param_defaults) {
						method_aux->param_defaults = image_g_new0 (image, guint8*, m->signature->param_count + 1);
						method_aux->param_default_types = image_g_new0 (image, guint32, m->signature->param_count + 1);
					}
					assembly = (MonoDynamicImage*)klass->image;
					idx = encode_constant (assembly, pb->def_value, &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;
					method_aux->param_defaults [i] = image_g_malloc (image, len);
					method_aux->param_default_types [i] = def_type;
					memcpy ((gpointer)method_aux->param_defaults [i], p, len);
				}

				if (pb->name) {
					method_aux->param_names [i] = mono_string_to_utf8_image (image, pb->name, &error);
					g_assert (mono_error_ok (&error));
				}
				if (pb->cattrs) {
					if (!method_aux->param_cattr)
						method_aux->param_cattr = image_g_new0 (image, MonoCustomAttrInfo*, m->signature->param_count + 1);
					method_aux->param_cattr [i] = mono_custom_attrs_from_builders (image, klass->image, pb->cattrs);
				}
			}
		}
	}

	/* Parameter marshalling */
	specs = NULL;
	if (rmb->pinfo)		
		for (i = 0; i < mono_array_length (rmb->pinfo); ++i) {
			MonoReflectionParamBuilder *pb;
			if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
				if (pb->marshal_info) {
					if (specs == NULL)
						specs = image_g_new0 (image, MonoMarshalSpec*, sig->param_count + 1);
					specs [pb->position] = 
						mono_marshal_spec_from_builder (image, klass->image->assembly, pb->marshal_info);
				}
			}
		}
	if (specs != NULL) {
		if (!method_aux)
			method_aux = image_g_new0 (image, MonoReflectionMethodAux, 1);
		method_aux->param_marshall = specs;
	}

	if (klass->image->dynamic && method_aux)
		g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);

	mono_loader_unlock ();

	return m;

Project: mono
File: verify.c

do_ldstr (VerifyContext *ctx, guint32 token)
{
	GSList *error = NULL;
	if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
		ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid string token %x at 0x%04x", token, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
		return;
	}

	if (!ctx->image->dynamic && !mono_verifier_verify_string_signature (ctx->image, mono_metadata_token_index (token), &error)) {
		if (error)
			ctx->list = g_slist_concat (ctx->list, error);
		ADD_VERIFY_ERROR2 (ctx, g_strdup_printf ("Invalid string index %x at 0x%04x", token, ctx->ip_offset), MONO_EXCEPTION_BAD_IMAGE);
		return;
	}

	if (check_overflow (ctx))
		stack_push_val (ctx, TYPE_COMPLEX,  &mono_defaults.string_class->byval_arg);
}

Project: mono
File: reflection.c

custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
{
	/* FIXME: Need to do more checks */
	if (cattr->ctor->method && (cattr->ctor->method->klass->image != image)) {
		int visibility = cattr->ctor->method->klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;

		if ((visibility != TYPE_ATTRIBUTE_PUBLIC) && (visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC))
			return FALSE;
	}

	return TRUE;
}

Project: mono
File: verify.c

in_any_exception_block (MonoMethodHeader *header, guint offset)
{
	int i;
	MonoExceptionClause *clause;

	for (i = 0; i < header->num_clauses; ++i) {
		clause = &header->clauses [i];
		if (MONO_OFFSET_IN_HANDLER (clause, offset))
			return TRUE;
		if (MONO_OFFSET_IN_FILTER (clause, offset))
			return TRUE;
	}
	return FALSE;
}

Project: mono
File: reflection.c

MonoReflectionMethod*
mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
{
	MonoClass *klass;
	MonoMethod *method, *inflated;
	MonoMethodInflated *imethod;
	MonoGenericContext tmp_context;
	MonoGenericInst *ginst;
	MonoType **type_argv;
	int count, i;

	MONO_ARCH_SAVE_REGS;

	/*FIXME but this no longer should happen*/
	if (!strcmp (rmethod->object.vtable->klass->name, "MethodBuilder")) {
#ifndef DISABLE_REFLECTION_EMIT
		MonoReflectionMethodBuilder *mb = NULL;
		MonoReflectionTypeBuilder *tb;
		MonoClass *klass;

		mb = (MonoReflectionMethodBuilder *) rmethod;
		tb = (MonoReflectionTypeBuilder *) mb->type;
		klass = mono_class_from_mono_type (mono_reflection_type_get_handle ((MonoReflectionType*)tb));

		method = methodbuilder_to_mono_method (klass, mb);
#else
		g_assert_not_reached ();
		method = NULL;
#endif
	} else {
		method = rmethod->method;
	}

	klass = method->klass;

	if (method->is_inflated)
		method = ((MonoMethodInflated *) method)->declaring;

	count = mono_method_signature (method)->generic_param_count;
	if (count != mono_array_length (types))
		return NULL;

	type_argv = g_new0 (MonoType *, count);
	for (i = 0; i < count; i++) {
		MonoReflectionType *garg = mono_array_get (types, gpointer, i);
		type_argv [i] = mono_reflection_type_get_handle (garg);
	}
	ginst = mono_metadata_get_generic_inst (count, type_argv);
	g_free (type_argv);

	tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
	tmp_context.method_inst = ginst;

	inflated = mono_class_inflate_generic_method (method, &tmp_context);
	imethod = (MonoMethodInflated *) inflated;

	/*FIXME but I think this is no longer necessary*/
	if (method->klass->image->dynamic) {
		MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
		/*
		 * This table maps metadata structures representing inflated methods/fields
		 * to the reflection objects representing their generic definitions.
		 */
		mono_loader_lock ();
		mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
		mono_loader_unlock ();
	}

	if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
		mono_raise_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
	
	return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);

Project: mono
File: verify.c

do_store_indirect (VerifyContext *ctx, int opcode)
{
	ILStackDesc *addr, *val;
	CLEAR_PREFIX (ctx, PREFIX_UNALIGNED | PREFIX_VOLATILE);

	if (!check_underflow (ctx, 2))
		return;

	val = stack_pop (ctx);
	addr = stack_pop (ctx);	

	check_unmanaged_pointer (ctx, addr);

	if (!stack_slot_is_managed_pointer (addr) && stack_slot_get_type (addr) != TYPE_PTR) {
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid non-pointer argument to stind at 0x%04x", ctx->ip_offset));
		return;
	}

	if (stack_slot_is_managed_mutability_pointer (addr)) {
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Cannot use a readonly pointer with stind at 0x%04x", ctx->ip_offset));
		return;
	}

	if (!verify_type_compatibility_full (ctx, mono_type_from_opcode (opcode), mono_type_get_type_byval (addr->type), TRUE))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid addr type at stack for stind 0x%x operation at 0x%04x", opcode, ctx->ip_offset));

	if (!verify_stack_type_compatibility (ctx, mono_type_from_opcode (opcode), val))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid value type at stack for stind 0x%x operation at 0x%04x", opcode, ctx->ip_offset));
}

Project: mono
File: reflection.c

property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb)
{
	SigBuffer buf;
	guint32 nparams = 0;
	MonoReflectionMethodBuilder *mb = fb->get_method;
	MonoReflectionMethodBuilder *smb = fb->set_method;
	guint32 idx, i;

	if (mb && mb->parameters)
		nparams = mono_array_length (mb->parameters);
	if (!mb && smb && smb->parameters)
		nparams = mono_array_length (smb->parameters) - 1;
	sigbuffer_init (&buf, 32);
	if (fb->call_conv & 0x20)
		sigbuffer_add_byte (&buf, 0x28);
	else
		sigbuffer_add_byte (&buf, 0x08);
	sigbuffer_add_value (&buf, nparams);
	if (mb) {
		encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf);
		for (i = 0; i < nparams; ++i) {
			MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
			encode_reflection_type (assembly, pt, &buf);
		}
	} else if (smb && smb->parameters) {
		/* the property type is the last param */
		encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf);
		for (i = 0; i < nparams; ++i) {
			MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
			encode_reflection_type (assembly, pt, &buf);
		}
	} else {
		encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
	}

	idx = sigbuffer_add_to_blob_cached (assembly, &buf);
	sigbuffer_free (&buf);
	return idx;
}

Project: mono
File: reflection.c

mono_reflection_get_custom_attrs_info (MonoObject *obj)
{
	MonoClass *klass;
	MonoCustomAttrInfo *cinfo = NULL;
	
	klass = obj->vtable->klass;
	if (klass == mono_defaults.monotype_class) {
		MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
		klass = mono_class_from_mono_type (type);
		/*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
		cinfo = mono_custom_attrs_from_class (klass);
	} else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
		MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
		cinfo = mono_custom_attrs_from_assembly (rassembly->assembly);
	} else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
		MonoReflectionModule *module = (MonoReflectionModule*)obj;
		cinfo = mono_custom_attrs_from_module (module->image);
	} else if (strcmp ("MonoProperty", klass->name) == 0) {
		MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
		cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property);
	} else if (strcmp ("MonoEvent", klass->name) == 0) {
		MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
		cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event);
	} else if (strcmp ("MonoField", klass->name) == 0) {
		MonoReflectionField *rfield = (MonoReflectionField*)obj;
		cinfo = mono_custom_attrs_from_field (rfield->field->parent, rfield->field);
	} else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
		MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
		cinfo = mono_custom_attrs_from_method (rmethod->method);
	} else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
		MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
		cinfo = mono_custom_attrs_from_method (rmethod->method);
	} else if (strcmp ("ParameterInfo", klass->name) == 0) {
		MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
		MonoClass *member_class = mono_object_class (param->MemberImpl);
		if (mono_class_is_reflection_method_or_constructor (member_class)) {
			MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
			cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
		} else if (is_sr_mono_property (member_class)) {
			MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
			MonoMethod *method;
			if (!(method = prop->property->get))
				method = prop->property->set;
			g_assert (method);

			cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
		} 
#ifndef DISABLE_REFLECTION_EMIT
		else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
			MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl);
			cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
		} else if (is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
			MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
			MonoMethod *method = NULL;
			if (is_sre_ctor_builder (mono_object_class (c->cb)))
				method = ((MonoReflectionCtorBuilder *)c->cb)->mhandle;
			else if (is_sr_mono_cmethod (mono_object_class (c->cb)))
				method = ((MonoReflectionMethod *)c->cb)->method;
			else
				g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));

			cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
		} 
#endif
		else {
			char *type_name = mono_type_get_full_name (member_class);
			char *msg = g_strdup_printf ("Custom attributes on a ParamInfo with member %s are not supported", type_name);
			MonoException *ex = mono_get_exception_not_supported  (msg);
			g_free (type_name);
			g_free (msg);
			mono_raise_exception (ex);
		}
	} else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
		MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
		cinfo = mono_custom_attrs_from_builders (NULL, assemblyb->assembly.assembly->image, assemblyb->cattrs);
	} else if (strcmp ("TypeBuilder", klass->name) == 0) {
		MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
		cinfo = mono_custom_attrs_from_builders (NULL, &tb->module->dynamic_image->image, tb->cattrs);
	} else if (strcmp ("ModuleBuilder", klass->name) == 0) {
		MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
		cinfo = mono_custom_attrs_from_builders (NULL, &mb->dynamic_image->image, mb->cattrs);
	} else if (strcmp ("ConstructorBuilder", klass->name) == 0) {
		MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
		cinfo = mono_custom_attrs_from_builders (NULL, cb->mhandle->klass->image, cb->cattrs);
	} else if (strcmp ("MethodBuilder", klass->name) == 0) {
		MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
		cinfo = mono_custom_attrs_from_builders (NULL, mb->mhandle->klass->image, mb->cattrs);
	} else if (strcmp ("FieldBuilder", klass->name) == 0) {
		MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
		cinfo = mono_custom_attrs_from_builders (NULL, &((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
	} else if (strcmp ("MonoGenericClass", klass->name) == 0) {
		MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)obj;
		cinfo = mono_reflection_get_custom_attrs_info ((MonoObject*)gclass->generic_type);
	} else { /* handle other types here... */
		g_error ("get custom attrs not yet supported for %s", klass->name);
	}

	return cinfo;
}

Project: mono
File: reflection.c

void
mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
{
	MonoReflectionTypeBuilder *tb;
	int i, onum;

	*overrides = NULL;
	*num_overrides = 0;

	g_assert (klass->image->dynamic);

	if (!mono_class_get_ref_info (klass))
		return;

	g_assert (strcmp (((MonoObject*)mono_class_get_ref_info (klass))->vtable->klass->name, "TypeBuilder") == 0);

	tb = (MonoReflectionTypeBuilder*)mono_class_get_ref_info (klass);

	onum = 0;
	if (tb->methods) {
		for (i = 0; i < tb->num_methods; ++i) {
			MonoReflectionMethodBuilder *mb = 
				mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
			if (mb->override_method)
				onum ++;
		}
	}

	if (onum) {
		*overrides = g_new0 (MonoMethod*, onum * 2);

		onum = 0;
		for (i = 0; i < tb->num_methods; ++i) {
			MonoReflectionMethodBuilder *mb = 
				mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
			if (mb->override_method) {
				(*overrides) [onum * 2] = mono_reflection_method_get_handle ((MonoObject *)mb->override_method);
				(*overrides) [onum * 2 + 1] = mb->mhandle;

				g_assert (mb->mhandle);

				onum ++;
			}
		}
	}

	*num_overrides = onum;

Project: mono
File: verify.c

char*
mono_verify_corlib ()
{
	/* This is a public API function so cannot be removed */
	return NULL;

Project: mono
File: verify.c

do_ldobj_value (VerifyContext *ctx, int token) 
{
	ILStackDesc *value;
	MonoType *type = get_boxable_mono_type (ctx, token, "ldobj");
	CLEAR_PREFIX (ctx, PREFIX_UNALIGNED | PREFIX_VOLATILE);

	if (!type)
		return;

	if (!check_underflow (ctx, 1))
		return;

	value = stack_pop (ctx);
	if (!stack_slot_is_managed_pointer (value) 
			&& stack_slot_get_type (value) != TYPE_NATIVE_INT
			&& !(stack_slot_get_type (value) == TYPE_PTR && value->type->type != MONO_TYPE_FNPTR)) {
		ADD_VERIFY_ERROR (ctx, g_strdup_printf ("Invalid argument %s to ldobj at 0x%04x", stack_slot_get_name (value), ctx->ip_offset));
		return;
	}

	if (stack_slot_get_type (value) == TYPE_NATIVE_INT)
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Using native pointer to ldobj at 0x%04x", ctx->ip_offset));

	/*We have a byval on the stack, but the comparison must be strict. */
	if (!verify_type_compatibility_full (ctx, type, mono_type_get_type_byval (value->type), TRUE))
		CODE_NOT_VERIFIABLE (ctx, g_strdup_printf ("Invalid type at stack for ldojb operation at 0x%04x", ctx->ip_offset));

	set_stack_value (ctx, stack_push (ctx), type, FALSE);
}

Project: mono
File: reflection.c

MonoArray *
mono_reflection_sighelper_get_signature_local (MonoReflectionSigHelper *sig)
{
	g_assert_not_reached ();
	return NULL;

Project: mono
File: verify.c

gboolean
mono_verifier_is_method_full_trust (MonoMethod *method)
{
	return mono_verifier_is_class_full_trust (method->klass);