예제 #1
0
	bool MonoMethod::hasAttribute(MonoClass* monoClass) const
	{
		// TODO - Consider caching custom attributes or just initializing them all at load

		MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(mMethod);
		if (attrInfo == nullptr)
			return false;

		bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->_getInternalClass()) != 0;

		mono_custom_attrs_free(attrInfo);

		return hasAttr;
	}
예제 #2
0
	MonoObject* MonoMethod::getAttribute(MonoClass* monoClass) const
	{
		// TODO - Consider caching custom attributes or just initializing them all at load

		MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(mMethod);
		if (attrInfo == nullptr)
			return nullptr;

		MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->_getInternalClass());

		mono_custom_attrs_free(attrInfo);

		return foundAttr;
	}
예제 #3
0
void GDMonoMethod::fetch_attributes() {
	ERR_FAIL_COND(attributes != NULL);
	attributes = mono_custom_attrs_from_method(mono_method);
	attrs_fetched = true;
}
예제 #4
0
파일: monodiet.c 프로젝트: ANahr/mono
static void
add_types_from_method (MonoMethod *method) {
	const MonoOpcode *opcode;
	MonoMethodHeader *header;
	const unsigned char *ip, *il_code_end;
	gpointer val = NULL, oldkey = NULL;
	int i, n;
	guint32 token;
	MonoClass *klass;
	MonoClassField *field;
	MonoCustomAttrInfo* cattrs;
	MonoType** locals;
	gpointer exc_iter;
	MonoExceptionClause clause;

	if (g_hash_table_lookup_extended (method_table, method, &oldkey, &val))
		return;
	g_hash_table_insert (method_table, method, NULL);

	g_assert (method->klass);

	if (verbose > 1)
		g_print ("#processing method: %s\n", mono_method_full_name (method, TRUE));
	mono_class_init (method->klass);
	cattrs = mono_custom_attrs_from_method (method);
	handle_cattrs (cattrs);
	add_type (method->klass);
	add_types_from_signature (mono_method_signature (method));
	for (i = 0; i < mono_method_signature (method)->param_count + 1; ++i) {
		cattrs = mono_custom_attrs_from_param (method, i);
		handle_cattrs (cattrs);
	}

	if (method->flags & METHOD_ATTRIBUTE_VIRTUAL)
		virtual_methods = g_list_prepend (virtual_methods, method);

	/* if no IL code to parse, return */
	if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME))
		return;
	if (method->flags & (METHOD_ATTRIBUTE_PINVOKE_IMPL | METHOD_ATTRIBUTE_ABSTRACT))
		return;

	header = mono_method_get_header (method);

	locals = mono_method_header_get_locals (header, &n, NULL);
	for (i = 0; i < n; ++i) {
		klass = mono_class_from_mono_type (locals [i]);
		add_type (klass);
	}
	for (exc_iter = NULL; mono_method_header_get_clauses (header, method, &exc_iter, &clause);) {
		if (clause.flags == MONO_EXCEPTION_CLAUSE_NONE)
			add_type (clause.data.catch_class);
	}

	ip = mono_method_header_get_code (header, &n, NULL);
	il_code_end = ip + n;

	while (ip < il_code_end) {
		if (verbose > 2)
			g_print ("#%s", mono_disasm_code_one (NULL, method, ip, NULL));
		if (*ip == 0xfe) {
			++ip;
			i = *ip + 256;
		} else {
			i = *ip;
		}

		opcode = &mono_opcodes [i];

		switch (opcode->argument) {
		case MonoInlineNone:
			ip++;
			break;
		case MonoInlineType:
			token = read32 (ip + 1);
			add_type (mono_class_get (method->klass->image, token));
			ip += 5;
			break;
		case MonoInlineField: {
			token = read32 (ip + 1);
			field = mono_field_from_token (method->klass->image, token, &klass, NULL);
			add_field (field);
			add_type (klass);
			ip += 5;
			break;
		}
		case MonoInlineTok:
		case MonoInlineSig:
			/* FIXME */
		case MonoInlineString:
		case MonoShortInlineR:
		case MonoInlineBrTarget:
		case MonoInlineI:
			ip += 5;
			break;
		case MonoInlineVar:
			ip += 3;
			break;
		case MonoShortInlineVar:
		case MonoShortInlineI:
		case MonoShortInlineBrTarget:
			ip += 2;
			break;
		case MonoInlineSwitch:
			++ip;
			n = read32 (ip);
			ip += 4;
			ip += 4 * n;
			break;
		case MonoInlineI8:
		case MonoInlineR:
			ip += 9;
			break;
		case MonoInlineMethod:
			{
				MonoMethod *cm = mono_get_method (method->klass->image, read32 (ip + 1), NULL);
				add_type (cm->klass);
				add_types_from_method (cm);
			}
			ip += 5;
			break;
		default:
			g_assert_not_reached ();
		}
	}
}